Index: user/ngie/stable-10-libnv/bin/ed/main.c =================================================================== --- user/ngie/stable-10-libnv/bin/ed/main.c (revision 292856) +++ user/ngie/stable-10-libnv/bin/ed/main.c (revision 292857) @@ -1,1417 +1,1419 @@ /* main.c: This file contains the main control and user-interface routines for the ed line editor. */ /*- * Copyright (c) 1993 Andrew Moore, Talke Studio. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef lint #if 0 static const char copyright[] = "@(#) Copyright (c) 1993 Andrew Moore, Talke Studio. \n\ All rights reserved.\n"; #endif #endif /* not lint */ #include __FBSDID("$FreeBSD$"); /* * CREDITS * * This program is based on the editor algorithm described in * Brian W. Kernighan and P. J. Plauger's book "Software Tools * in Pascal," Addison-Wesley, 1981. * * The buffering algorithm is attributed to Rodney Ruddock of * the University of Guelph, Guelph, Ontario. * * The cbc.c encryption code is adapted from * the bdes program by Matt Bishop of Dartmouth College, * Hanover, NH. * */ #include #include #include #include #include #include #include #include "ed.h" #ifdef _POSIX_SOURCE static sigjmp_buf env; #else static jmp_buf env; #endif /* static buffers */ char stdinbuf[1]; /* stdin buffer */ static char *shcmd; /* shell command buffer */ static int shcmdsz; /* shell command buffer size */ static int shcmdi; /* shell command buffer index */ char *ibuf; /* ed command-line buffer */ int ibufsz; /* ed command-line buffer size */ char *ibufp; /* pointer to ed command-line buffer */ /* global flags */ int des = 0; /* if set, use crypt(3) for i/o */ static int garrulous = 0; /* if set, print all error messages */ int isbinary; /* if set, buffer contains ASCII NULs */ int isglobal; /* if set, doing a global command */ int modified; /* if set, buffer modified since last write */ int mutex = 0; /* if set, signals set "sigflags" */ static int red = 0; /* if set, restrict shell/directory access */ int scripted = 0; /* if set, suppress diagnostics */ int sigflags = 0; /* if set, signals received while mutex set */ static int sigactive = 0; /* if set, signal handlers are enabled */ static char old_filename[PATH_MAX] = ""; /* default filename */ long current_addr; /* current address in editor buffer */ long addr_last; /* last address in editor buffer */ int lineno; /* script line number */ static const char *prompt; /* command-line prompt */ static const char *dps = "*"; /* default command-line prompt */ static const char *usage = "usage: %s [-] [-sx] [-p string] [file]\n"; /* ed: line editor */ int main(volatile int argc, char ** volatile argv) { int c, n; long status = 0; (void)setlocale(LC_ALL, ""); red = (n = strlen(argv[0])) > 2 && argv[0][n - 3] == 'r'; top: while ((c = getopt(argc, argv, "p:sx")) != -1) switch(c) { case 'p': /* set prompt */ prompt = optarg; break; case 's': /* run script */ scripted = 1; break; case 'x': /* use crypt */ #ifdef DES des = get_keyword(); #else fprintf(stderr, "crypt unavailable\n?\n"); #endif break; default: fprintf(stderr, usage, red ? "red" : "ed"); exit(1); } argv += optind; argc -= optind; if (argc && **argv == '-') { scripted = 1; if (argc > 1) { optind = 1; goto top; } argv++; argc--; } /* assert: reliable signals! */ #ifdef SIGWINCH handle_winch(SIGWINCH); if (isatty(0)) signal(SIGWINCH, handle_winch); #endif signal(SIGHUP, signal_hup); signal(SIGQUIT, SIG_IGN); signal(SIGINT, signal_int); #ifdef _POSIX_SOURCE if ((status = sigsetjmp(env, 1))) #else if ((status = setjmp(env))) #endif { fputs("\n?\n", stderr); errmsg = "interrupt"; } else { init_buffers(); sigactive = 1; /* enable signal handlers */ if (argc && **argv && is_legal_filename(*argv)) { if (read_file(*argv, 0) < 0 && !isatty(0)) quit(2); else if (**argv != '!') if (strlcpy(old_filename, *argv, sizeof(old_filename)) >= sizeof(old_filename)) quit(2); } else if (argc) { fputs("?\n", stderr); if (**argv == '\0') errmsg = "invalid filename"; if (!isatty(0)) quit(2); } } for (;;) { if (status < 0 && garrulous) fprintf(stderr, "%s\n", errmsg); if (prompt) { printf("%s", prompt); fflush(stdout); } if ((n = get_tty_line()) < 0) { status = ERR; continue; } else if (n == 0) { if (modified && !scripted) { fputs("?\n", stderr); errmsg = "warning: file modified"; if (!isatty(0)) { if (garrulous) fprintf(stderr, "script, line %d: %s\n", lineno, errmsg); quit(2); } clearerr(stdin); modified = 0; status = EMOD; continue; } else quit(0); } else if (ibuf[n - 1] != '\n') { /* discard line */ errmsg = "unexpected end-of-file"; clearerr(stdin); status = ERR; continue; } isglobal = 0; if ((status = extract_addr_range()) >= 0 && (status = exec_command()) >= 0) if (!status || (status = display_lines(current_addr, current_addr, status)) >= 0) continue; switch (status) { case EOF: quit(0); case EMOD: modified = 0; fputs("?\n", stderr); /* give warning */ errmsg = "warning: file modified"; if (!isatty(0)) { if (garrulous) fprintf(stderr, "script, line %d: %s\n", lineno, errmsg); quit(2); } break; case FATAL: if (!isatty(0)) { if (garrulous) fprintf(stderr, "script, line %d: %s\n", lineno, errmsg); } else if (garrulous) fprintf(stderr, "%s\n", errmsg); quit(3); default: fputs("?\n", stderr); if (!isatty(0)) { if (garrulous) fprintf(stderr, "script, line %d: %s\n", lineno, errmsg); quit(2); } break; } } /*NOTREACHED*/ } long first_addr, second_addr; static long addr_cnt; /* extract_addr_range: get line addresses from the command buffer until an illegal address is seen; return status */ int extract_addr_range(void) { long addr; addr_cnt = 0; first_addr = second_addr = current_addr; while ((addr = next_addr()) >= 0) { addr_cnt++; first_addr = second_addr; second_addr = addr; if (*ibufp != ',' && *ibufp != ';') break; else if (*ibufp++ == ';') current_addr = addr; } if ((addr_cnt = min(addr_cnt, 2)) == 1 || second_addr != addr) first_addr = second_addr; return (addr == ERR) ? ERR : 0; } #define SKIP_BLANKS() while (isspace((unsigned char)*ibufp) && *ibufp != '\n') ibufp++ #define MUST_BE_FIRST() do { \ if (!first) { \ errmsg = "invalid address"; \ return ERR; \ } \ } while (0) /* next_addr: return the next line address in the command buffer */ long next_addr(void) { const char *hd; long addr = current_addr; long n; int first = 1; int c; SKIP_BLANKS(); for (hd = ibufp;; first = 0) switch (c = *ibufp) { case '+': case '\t': case ' ': case '-': case '^': ibufp++; SKIP_BLANKS(); if (isdigit((unsigned char)*ibufp)) { STRTOL(n, ibufp); addr += (c == '-' || c == '^') ? -n : n; } else if (!isspace((unsigned char)c)) addr += (c == '-' || c == '^') ? -1 : 1; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': MUST_BE_FIRST(); STRTOL(addr, ibufp); break; case '.': case '$': MUST_BE_FIRST(); ibufp++; addr = (c == '.') ? current_addr : addr_last; break; case '/': case '?': MUST_BE_FIRST(); if ((addr = get_matching_node_addr( get_compiled_pattern(), c == '/')) < 0) return ERR; else if (c == *ibufp) ibufp++; break; case '\'': MUST_BE_FIRST(); ibufp++; if ((addr = get_marked_node_addr(*ibufp++)) < 0) return ERR; break; case '%': case ',': case ';': if (first) { ibufp++; addr_cnt++; second_addr = (c == ';') ? current_addr : 1; addr = addr_last; break; } /* FALLTHROUGH */ default: if (ibufp == hd) return EOF; else if (addr < 0 || addr_last < addr) { errmsg = "invalid address"; return ERR; } else return addr; } /* NOTREACHED */ } #ifdef BACKWARDS /* GET_THIRD_ADDR: get a legal address from the command buffer */ #define GET_THIRD_ADDR(addr) \ { \ long ol1, ol2; \ \ ol1 = first_addr, ol2 = second_addr; \ if (extract_addr_range() < 0) \ return ERR; \ else if (addr_cnt == 0) { \ errmsg = "destination expected"; \ return ERR; \ } else if (second_addr < 0 || addr_last < second_addr) { \ errmsg = "invalid address"; \ return ERR; \ } \ addr = second_addr; \ first_addr = ol1, second_addr = ol2; \ } #else /* BACKWARDS */ /* GET_THIRD_ADDR: get a legal address from the command buffer */ #define GET_THIRD_ADDR(addr) \ { \ long ol1, ol2; \ \ ol1 = first_addr, ol2 = second_addr; \ if (extract_addr_range() < 0) \ return ERR; \ if (second_addr < 0 || addr_last < second_addr) { \ errmsg = "invalid address"; \ return ERR; \ } \ addr = second_addr; \ first_addr = ol1, second_addr = ol2; \ } #endif /* GET_COMMAND_SUFFIX: verify the command suffix in the command buffer */ #define GET_COMMAND_SUFFIX() { \ int done = 0; \ do { \ switch(*ibufp) { \ case 'p': \ gflag |= GPR, ibufp++; \ break; \ case 'l': \ gflag |= GLS, ibufp++; \ break; \ case 'n': \ gflag |= GNP, ibufp++; \ break; \ default: \ done++; \ } \ } while (!done); \ if (*ibufp++ != '\n') { \ errmsg = "invalid command suffix"; \ return ERR; \ } \ } /* sflags */ #define SGG 001 /* complement previous global substitute suffix */ #define SGP 002 /* complement previous print suffix */ #define SGR 004 /* use last regex instead of last pat */ #define SGF 010 /* repeat last substitution */ int patlock = 0; /* if set, pattern not freed by get_compiled_pattern() */ long rows = 22; /* scroll length: ws_row - 2 */ /* exec_command: execute the next command in command buffer; return print request, if any */ int exec_command(void) { static pattern_t *pat = NULL; static int sgflag = 0; static long sgnum = 0; pattern_t *tpat; char *fnp; int gflag = 0; int sflags = 0; long addr = 0; int n = 0; int c; SKIP_BLANKS(); switch(c = *ibufp++) { case 'a': GET_COMMAND_SUFFIX(); if (!isglobal) clear_undo_stack(); if (append_lines(second_addr) < 0) return ERR; break; case 'c': if (check_addr_range(current_addr, current_addr) < 0) return ERR; GET_COMMAND_SUFFIX(); if (!isglobal) clear_undo_stack(); if (delete_lines(first_addr, second_addr) < 0 || append_lines(current_addr) < 0) return ERR; break; case 'd': if (check_addr_range(current_addr, current_addr) < 0) return ERR; GET_COMMAND_SUFFIX(); if (!isglobal) clear_undo_stack(); if (delete_lines(first_addr, second_addr) < 0) return ERR; else if ((addr = INC_MOD(current_addr, addr_last)) != 0) current_addr = addr; break; case 'e': if (modified && !scripted) return EMOD; /* FALLTHROUGH */ case 'E': if (addr_cnt > 0) { errmsg = "unexpected address"; return ERR; } else if (!isspace((unsigned char)*ibufp)) { errmsg = "unexpected command suffix"; return ERR; } else if ((fnp = get_filename()) == NULL) return ERR; GET_COMMAND_SUFFIX(); if (delete_lines(1, addr_last) < 0) return ERR; clear_undo_stack(); if (close_sbuf() < 0) return ERR; else if (open_sbuf() < 0) return FATAL; - if (*fnp && *fnp != '!') strcpy(old_filename, fnp); + if (*fnp && *fnp != '!') + strlcpy(old_filename, fnp, PATH_MAX); #ifdef BACKWARDS if (*fnp == '\0' && *old_filename == '\0') { errmsg = "no current filename"; return ERR; } #endif if (read_file(*fnp ? fnp : old_filename, 0) < 0) return ERR; clear_undo_stack(); modified = 0; u_current_addr = u_addr_last = -1; break; case 'f': if (addr_cnt > 0) { errmsg = "unexpected address"; return ERR; } else if (!isspace((unsigned char)*ibufp)) { errmsg = "unexpected command suffix"; return ERR; } else if ((fnp = get_filename()) == NULL) return ERR; else if (*fnp == '!') { errmsg = "invalid redirection"; return ERR; } GET_COMMAND_SUFFIX(); - if (*fnp) strcpy(old_filename, fnp); + if (*fnp) + strlcpy(old_filename, fnp, PATH_MAX); printf("%s\n", strip_escapes(old_filename)); break; case 'g': case 'v': case 'G': case 'V': if (isglobal) { errmsg = "cannot nest global commands"; return ERR; } else if (check_addr_range(1, addr_last) < 0) return ERR; else if (build_active_list(c == 'g' || c == 'G') < 0) return ERR; else if ((n = (c == 'G' || c == 'V'))) GET_COMMAND_SUFFIX(); isglobal++; if (exec_global(n, gflag) < 0) return ERR; break; case 'h': if (addr_cnt > 0) { errmsg = "unexpected address"; return ERR; } GET_COMMAND_SUFFIX(); if (*errmsg) fprintf(stderr, "%s\n", errmsg); break; case 'H': if (addr_cnt > 0) { errmsg = "unexpected address"; return ERR; } GET_COMMAND_SUFFIX(); if ((garrulous = 1 - garrulous) && *errmsg) fprintf(stderr, "%s\n", errmsg); break; case 'i': if (second_addr == 0) { errmsg = "invalid address"; return ERR; } GET_COMMAND_SUFFIX(); if (!isglobal) clear_undo_stack(); if (append_lines(second_addr - 1) < 0) return ERR; break; case 'j': if (check_addr_range(current_addr, current_addr + 1) < 0) return ERR; GET_COMMAND_SUFFIX(); if (!isglobal) clear_undo_stack(); if (first_addr != second_addr && join_lines(first_addr, second_addr) < 0) return ERR; break; case 'k': c = *ibufp++; if (second_addr == 0) { errmsg = "invalid address"; return ERR; } GET_COMMAND_SUFFIX(); if (mark_line_node(get_addressed_line_node(second_addr), c) < 0) return ERR; break; case 'l': if (check_addr_range(current_addr, current_addr) < 0) return ERR; GET_COMMAND_SUFFIX(); if (display_lines(first_addr, second_addr, gflag | GLS) < 0) return ERR; gflag = 0; break; case 'm': if (check_addr_range(current_addr, current_addr) < 0) return ERR; GET_THIRD_ADDR(addr); if (first_addr <= addr && addr < second_addr) { errmsg = "invalid destination"; return ERR; } GET_COMMAND_SUFFIX(); if (!isglobal) clear_undo_stack(); if (move_lines(addr) < 0) return ERR; break; case 'n': if (check_addr_range(current_addr, current_addr) < 0) return ERR; GET_COMMAND_SUFFIX(); if (display_lines(first_addr, second_addr, gflag | GNP) < 0) return ERR; gflag = 0; break; case 'p': if (check_addr_range(current_addr, current_addr) < 0) return ERR; GET_COMMAND_SUFFIX(); if (display_lines(first_addr, second_addr, gflag | GPR) < 0) return ERR; gflag = 0; break; case 'P': if (addr_cnt > 0) { errmsg = "unexpected address"; return ERR; } GET_COMMAND_SUFFIX(); prompt = prompt ? NULL : optarg ? optarg : dps; break; case 'q': case 'Q': if (addr_cnt > 0) { errmsg = "unexpected address"; return ERR; } GET_COMMAND_SUFFIX(); gflag = (modified && !scripted && c == 'q') ? EMOD : EOF; break; case 'r': if (!isspace((unsigned char)*ibufp)) { errmsg = "unexpected command suffix"; return ERR; } else if (addr_cnt == 0) second_addr = addr_last; if ((fnp = get_filename()) == NULL) return ERR; GET_COMMAND_SUFFIX(); if (!isglobal) clear_undo_stack(); if (*old_filename == '\0' && *fnp != '!') - strcpy(old_filename, fnp); + strlcpy(old_filename, fnp, PATH_MAX); #ifdef BACKWARDS if (*fnp == '\0' && *old_filename == '\0') { errmsg = "no current filename"; return ERR; } #endif if ((addr = read_file(*fnp ? fnp : old_filename, second_addr)) < 0) return ERR; else if (addr && addr != addr_last) modified = 1; break; case 's': do { switch(*ibufp) { case '\n': sflags |=SGF; break; case 'g': sflags |= SGG; ibufp++; break; case 'p': sflags |= SGP; ibufp++; break; case 'r': sflags |= SGR; ibufp++; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': STRTOL(sgnum, ibufp); sflags |= SGF; sgflag &= ~GSG; /* override GSG */ break; default: if (sflags) { errmsg = "invalid command suffix"; return ERR; } } } while (sflags && *ibufp != '\n'); if (sflags && !pat) { errmsg = "no previous substitution"; return ERR; } else if (sflags & SGG) sgnum = 0; /* override numeric arg */ if (*ibufp != '\n' && *(ibufp + 1) == '\n') { errmsg = "invalid pattern delimiter"; return ERR; } tpat = pat; SPL1(); if ((!sflags || (sflags & SGR)) && (tpat = get_compiled_pattern()) == NULL) { SPL0(); return ERR; } else if (tpat != pat) { if (pat) { regfree(pat); free(pat); } pat = tpat; patlock = 1; /* reserve pattern */ } SPL0(); if (!sflags && extract_subst_tail(&sgflag, &sgnum) < 0) return ERR; else if (isglobal) sgflag |= GLB; else sgflag &= ~GLB; if (sflags & SGG) sgflag ^= GSG; if (sflags & SGP) sgflag ^= GPR, sgflag &= ~(GLS | GNP); do { switch(*ibufp) { case 'p': sgflag |= GPR, ibufp++; break; case 'l': sgflag |= GLS, ibufp++; break; case 'n': sgflag |= GNP, ibufp++; break; default: n++; } } while (!n); if (check_addr_range(current_addr, current_addr) < 0) return ERR; GET_COMMAND_SUFFIX(); if (!isglobal) clear_undo_stack(); if (search_and_replace(pat, sgflag, sgnum) < 0) return ERR; break; case 't': if (check_addr_range(current_addr, current_addr) < 0) return ERR; GET_THIRD_ADDR(addr); GET_COMMAND_SUFFIX(); if (!isglobal) clear_undo_stack(); if (copy_lines(addr) < 0) return ERR; break; case 'u': if (addr_cnt > 0) { errmsg = "unexpected address"; return ERR; } GET_COMMAND_SUFFIX(); if (pop_undo_stack() < 0) return ERR; break; case 'w': case 'W': if ((n = *ibufp) == 'q' || n == 'Q') { gflag = EOF; ibufp++; } if (!isspace((unsigned char)*ibufp)) { errmsg = "unexpected command suffix"; return ERR; } else if ((fnp = get_filename()) == NULL) return ERR; if (addr_cnt == 0 && !addr_last) first_addr = second_addr = 0; else if (check_addr_range(1, addr_last) < 0) return ERR; GET_COMMAND_SUFFIX(); if (*old_filename == '\0' && *fnp != '!') - strcpy(old_filename, fnp); + strlcpy(old_filename, fnp, PATH_MAX); #ifdef BACKWARDS if (*fnp == '\0' && *old_filename == '\0') { errmsg = "no current filename"; return ERR; } #endif if ((addr = write_file(*fnp ? fnp : old_filename, (c == 'W') ? "a" : "w", first_addr, second_addr)) < 0) return ERR; else if (addr == addr_last) modified = 0; else if (modified && !scripted && n == 'q') gflag = EMOD; break; case 'x': if (addr_cnt > 0) { errmsg = "unexpected address"; return ERR; } GET_COMMAND_SUFFIX(); #ifdef DES des = get_keyword(); break; #else errmsg = "crypt unavailable"; return ERR; #endif case 'z': #ifdef BACKWARDS if (check_addr_range(first_addr = 1, current_addr + 1) < 0) #else if (check_addr_range(first_addr = 1, current_addr + !isglobal) < 0) #endif return ERR; else if ('0' < *ibufp && *ibufp <= '9') STRTOL(rows, ibufp); GET_COMMAND_SUFFIX(); if (display_lines(second_addr, min(addr_last, second_addr + rows), gflag) < 0) return ERR; gflag = 0; break; case '=': GET_COMMAND_SUFFIX(); printf("%ld\n", addr_cnt ? second_addr : addr_last); break; case '!': if (addr_cnt > 0) { errmsg = "unexpected address"; return ERR; } else if ((sflags = get_shell_command()) < 0) return ERR; GET_COMMAND_SUFFIX(); if (sflags) printf("%s\n", shcmd + 1); system(shcmd + 1); if (!scripted) printf("!\n"); break; case '\n': #ifdef BACKWARDS if (check_addr_range(first_addr = 1, current_addr + 1) < 0 #else if (check_addr_range(first_addr = 1, current_addr + !isglobal) < 0 #endif || display_lines(second_addr, second_addr, 0) < 0) return ERR; break; default: errmsg = "unknown command"; return ERR; } return gflag; } /* check_addr_range: return status of address range check */ int check_addr_range(long n, long m) { if (addr_cnt == 0) { first_addr = n; second_addr = m; } if (first_addr > second_addr || 1 > first_addr || second_addr > addr_last) { errmsg = "invalid address"; return ERR; } return 0; } /* get_matching_node_addr: return the address of the next line matching a pattern in a given direction. wrap around begin/end of editor buffer if necessary */ long get_matching_node_addr(pattern_t *pat, int dir) { char *s; long n = current_addr; line_t *lp; if (!pat) return ERR; do { if ((n = dir ? INC_MOD(n, addr_last) : DEC_MOD(n, addr_last))) { lp = get_addressed_line_node(n); if ((s = get_sbuf_line(lp)) == NULL) return ERR; if (isbinary) NUL_TO_NEWLINE(s, lp->len); if (!regexec(pat, s, 0, NULL, 0)) return n; } } while (n != current_addr); errmsg = "no match"; return ERR; } /* get_filename: return pointer to copy of filename in the command buffer */ char * get_filename(void) { static char *file = NULL; static int filesz = 0; int n; if (*ibufp != '\n') { SKIP_BLANKS(); if (*ibufp == '\n') { errmsg = "invalid filename"; return NULL; } else if ((ibufp = get_extended_line(&n, 1)) == NULL) return NULL; else if (*ibufp == '!') { ibufp++; if ((n = get_shell_command()) < 0) return NULL; if (n) printf("%s\n", shcmd + 1); return shcmd; } else if (n > PATH_MAX - 1) { errmsg = "filename too long"; return NULL; } } #ifndef BACKWARDS else if (*old_filename == '\0') { errmsg = "no current filename"; return NULL; } #endif REALLOC(file, filesz, PATH_MAX, NULL); for (n = 0; *ibufp != '\n';) file[n++] = *ibufp++; file[n] = '\0'; return is_legal_filename(file) ? file : NULL; } /* get_shell_command: read a shell command from stdin; return substitution status */ int get_shell_command(void) { static char *buf = NULL; static int n = 0; char *s; /* substitution char pointer */ int i = 0; int j = 0; if (red) { errmsg = "shell access restricted"; return ERR; } else if ((s = ibufp = get_extended_line(&j, 1)) == NULL) return ERR; REALLOC(buf, n, j + 1, ERR); buf[i++] = '!'; /* prefix command w/ bang */ while (*ibufp != '\n') switch (*ibufp) { default: REALLOC(buf, n, i + 2, ERR); buf[i++] = *ibufp; if (*ibufp++ == '\\') buf[i++] = *ibufp++; break; case '!': if (s != ibufp) { REALLOC(buf, n, i + 1, ERR); buf[i++] = *ibufp++; } #ifdef BACKWARDS else if (shcmd == NULL || *(shcmd + 1) == '\0') #else else if (shcmd == NULL) #endif { errmsg = "no previous command"; return ERR; } else { REALLOC(buf, n, i + shcmdi, ERR); for (s = shcmd + 1; s < shcmd + shcmdi;) buf[i++] = *s++; s = ibufp++; } break; case '%': if (*old_filename == '\0') { errmsg = "no current filename"; return ERR; } j = strlen(s = strip_escapes(old_filename)); REALLOC(buf, n, i + j, ERR); while (j--) buf[i++] = *s++; s = ibufp++; break; } REALLOC(shcmd, shcmdsz, i + 1, ERR); memcpy(shcmd, buf, i); shcmd[shcmdi = i] = '\0'; return *s == '!' || *s == '%'; } /* append_lines: insert text from stdin to after line n; stop when either a single period is read or EOF; return status */ int append_lines(long n) { int l; const char *lp = ibuf; const char *eot; undo_t *up = NULL; for (current_addr = n;;) { if (!isglobal) { if ((l = get_tty_line()) < 0) return ERR; else if (l == 0 || ibuf[l - 1] != '\n') { clearerr(stdin); return l ? EOF : 0; } lp = ibuf; } else if (*(lp = ibufp) == '\0') return 0; else { while (*ibufp++ != '\n') ; l = ibufp - lp; } if (l == 2 && lp[0] == '.' && lp[1] == '\n') { return 0; } eot = lp + l; SPL1(); do { if ((lp = put_sbuf_line(lp)) == NULL) { SPL0(); return ERR; } else if (up) up->t = get_addressed_line_node(current_addr); else if ((up = push_undo_stack(UADD, current_addr, current_addr)) == NULL) { SPL0(); return ERR; } } while (lp != eot); modified = 1; SPL0(); } /* NOTREACHED */ } /* join_lines: replace a range of lines with the joined text of those lines */ int join_lines(long from, long to) { static char *buf = NULL; static int n; char *s; int size = 0; line_t *bp, *ep; ep = get_addressed_line_node(INC_MOD(to, addr_last)); bp = get_addressed_line_node(from); for (; bp != ep; bp = bp->q_forw) { if ((s = get_sbuf_line(bp)) == NULL) return ERR; REALLOC(buf, n, size + bp->len, ERR); memcpy(buf + size, s, bp->len); size += bp->len; } REALLOC(buf, n, size + 2, ERR); memcpy(buf + size, "\n", 2); if (delete_lines(from, to) < 0) return ERR; current_addr = from - 1; SPL1(); if (put_sbuf_line(buf) == NULL || push_undo_stack(UADD, current_addr, current_addr) == NULL) { SPL0(); return ERR; } modified = 1; SPL0(); return 0; } /* move_lines: move a range of lines */ int move_lines(long addr) { line_t *b1, *a1, *b2, *a2; long n = INC_MOD(second_addr, addr_last); long p = first_addr - 1; int done = (addr == first_addr - 1 || addr == second_addr); SPL1(); if (done) { a2 = get_addressed_line_node(n); b2 = get_addressed_line_node(p); current_addr = second_addr; } else if (push_undo_stack(UMOV, p, n) == NULL || push_undo_stack(UMOV, addr, INC_MOD(addr, addr_last)) == NULL) { SPL0(); return ERR; } else { a1 = get_addressed_line_node(n); if (addr < first_addr) { b1 = get_addressed_line_node(p); b2 = get_addressed_line_node(addr); /* this get_addressed_line_node last! */ } else { b2 = get_addressed_line_node(addr); b1 = get_addressed_line_node(p); /* this get_addressed_line_node last! */ } a2 = b2->q_forw; REQUE(b2, b1->q_forw); REQUE(a1->q_back, a2); REQUE(b1, a1); current_addr = addr + ((addr < first_addr) ? second_addr - first_addr + 1 : 0); } if (isglobal) unset_active_nodes(b2->q_forw, a2); modified = 1; SPL0(); return 0; } /* copy_lines: copy a range of lines; return status */ int copy_lines(long addr) { line_t *lp, *np = get_addressed_line_node(first_addr); undo_t *up = NULL; long n = second_addr - first_addr + 1; long m = 0; current_addr = addr; if (first_addr <= addr && addr < second_addr) { n = addr - first_addr + 1; m = second_addr - addr; } for (; n > 0; n=m, m=0, np = get_addressed_line_node(current_addr + 1)) for (; n-- > 0; np = np->q_forw) { SPL1(); if ((lp = dup_line_node(np)) == NULL) { SPL0(); return ERR; } add_line_node(lp); if (up) up->t = lp; else if ((up = push_undo_stack(UADD, current_addr, current_addr)) == NULL) { SPL0(); return ERR; } modified = 1; SPL0(); } return 0; } /* delete_lines: delete a range of lines */ int delete_lines(long from, long to) { line_t *n, *p; SPL1(); if (push_undo_stack(UDEL, from, to) == NULL) { SPL0(); return ERR; } n = get_addressed_line_node(INC_MOD(to, addr_last)); p = get_addressed_line_node(from - 1); /* this get_addressed_line_node last! */ if (isglobal) unset_active_nodes(p->q_forw, n); REQUE(p, n); addr_last -= to - from + 1; current_addr = from - 1; modified = 1; SPL0(); return 0; } /* display_lines: print a range of lines to stdout */ int display_lines(long from, long to, int gflag) { line_t *bp; line_t *ep; char *s; if (!from) { errmsg = "invalid address"; return ERR; } ep = get_addressed_line_node(INC_MOD(to, addr_last)); bp = get_addressed_line_node(from); for (; bp != ep; bp = bp->q_forw) { if ((s = get_sbuf_line(bp)) == NULL) return ERR; if (put_tty_line(s, bp->len, current_addr = from++, gflag) < 0) return ERR; } return 0; } #define MAXMARK 26 /* max number of marks */ static line_t *mark[MAXMARK]; /* line markers */ static int markno; /* line marker count */ /* mark_line_node: set a line node mark */ int mark_line_node(line_t *lp, int n) { if (!islower((unsigned char)n)) { errmsg = "invalid mark character"; return ERR; } else if (mark[n - 'a'] == NULL) markno++; mark[n - 'a'] = lp; return 0; } /* get_marked_node_addr: return address of a marked line */ long get_marked_node_addr(int n) { if (!islower((unsigned char)n)) { errmsg = "invalid mark character"; return ERR; } return get_line_node_addr(mark[n - 'a']); } /* unmark_line_node: clear line node mark */ void unmark_line_node(line_t *lp) { int i; for (i = 0; markno && i < MAXMARK; i++) if (mark[i] == lp) { mark[i] = NULL; markno--; } } /* dup_line_node: return a pointer to a copy of a line node */ line_t * dup_line_node(line_t *lp) { line_t *np; if ((np = (line_t *) malloc(sizeof(line_t))) == NULL) { fprintf(stderr, "%s\n", strerror(errno)); errmsg = "out of memory"; return NULL; } np->seek = lp->seek; np->len = lp->len; return np; } /* has_trailing_escape: return the parity of escapes preceding a character in a string */ int has_trailing_escape(char *s, char *t) { return (s == t || *(t - 1) != '\\') ? 0 : !has_trailing_escape(s, t - 1); } /* strip_escapes: return copy of escaped string of at most length PATH_MAX */ char * strip_escapes(char *s) { static char *file = NULL; static int filesz = 0; int i = 0; REALLOC(file, filesz, PATH_MAX, NULL); while (i < filesz - 1 /* Worry about a possible trailing escape */ && (file[i++] = (*s == '\\') ? *++s : *s)) s++; return file; } void signal_hup(int signo) { if (mutex) sigflags |= (1 << (signo - 1)); else handle_hup(signo); } void signal_int(int signo) { if (mutex) sigflags |= (1 << (signo - 1)); else handle_int(signo); } void handle_hup(int signo) { char *hup = NULL; /* hup filename */ char *s; char ed_hup[] = "ed.hup"; int n; if (!sigactive) quit(1); sigflags &= ~(1 << (signo - 1)); if (addr_last && write_file(ed_hup, "w", 1, addr_last) < 0 && (s = getenv("HOME")) != NULL && (n = strlen(s)) + 8 <= PATH_MAX && /* "ed.hup" + '/' */ (hup = (char *) malloc(n + 10)) != NULL) { strcpy(hup, s); if (hup[n - 1] != '/') hup[n] = '/', hup[n+1] = '\0'; strcat(hup, "ed.hup"); write_file(hup, "w", 1, addr_last); } quit(2); } void handle_int(int signo) { if (!sigactive) quit(1); sigflags &= ~(1 << (signo - 1)); #ifdef _POSIX_SOURCE siglongjmp(env, -1); #else longjmp(env, -1); #endif } int cols = 72; /* wrap column */ void handle_winch(int signo) { int save_errno = errno; struct winsize ws; /* window size structure */ sigflags &= ~(1 << (signo - 1)); if (ioctl(0, TIOCGWINSZ, (char *) &ws) >= 0) { if (ws.ws_row > 2) rows = ws.ws_row - 2; if (ws.ws_col > 8) cols = ws.ws_col - 8; } errno = save_errno; } /* is_legal_filename: return a legal filename */ int is_legal_filename(char *s) { if (red && (*s == '!' || !strcmp(s, "..") || strchr(s, '/'))) { errmsg = "shell access restricted"; return 0; } return 1; } Index: user/ngie/stable-10-libnv/bin/sh/mknodes.c =================================================================== --- user/ngie/stable-10-libnv/bin/sh/mknodes.c (revision 292856) +++ user/ngie/stable-10-libnv/bin/sh/mknodes.c (revision 292857) @@ -1,449 +1,459 @@ /*- * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Kenneth Almquist. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if 0 #ifndef lint static char const copyright[] = "@(#) Copyright (c) 1991, 1993\n\ The Regents of the University of California. All rights reserved.\n"; #endif /* not lint */ #ifndef lint static char sccsid[] = "@(#)mknodes.c 8.2 (Berkeley) 5/4/95"; #endif /* not lint */ #endif #include __FBSDID("$FreeBSD$"); /* * This program reads the nodetypes file and nodes.c.pat file. It generates * the files nodes.h and nodes.c. */ #include #include #include #include #include #define MAXTYPES 50 /* max number of node types */ #define MAXFIELDS 20 /* max fields in a structure */ #define BUFLEN 100 /* size of character buffers */ /* field types */ #define T_NODE 1 /* union node *field */ #define T_NODELIST 2 /* struct nodelist *field */ #define T_STRING 3 #define T_INT 4 /* int field */ #define T_OTHER 5 /* other */ #define T_TEMP 6 /* don't copy this field */ struct field { /* a structure field */ char *name; /* name of field */ int type; /* type of field */ char *decl; /* declaration of field */ }; struct str { /* struct representing a node structure */ char *tag; /* structure tag */ int nfields; /* number of fields in the structure */ struct field field[MAXFIELDS]; /* the fields of the structure */ int done; /* set if fully parsed */ }; static int ntypes; /* number of node types */ static char *nodename[MAXTYPES]; /* names of the nodes */ static struct str *nodestr[MAXTYPES]; /* type of structure used by the node */ static int nstr; /* number of structures */ static struct str str[MAXTYPES]; /* the structures */ static struct str *curstr; /* current structure */ -static FILE *infp; static char line[1024]; static int linno; static char *linep; static void parsenode(void); static void parsefield(void); static void output(char *); static void outsizes(FILE *); static void outfunc(FILE *, int); static void indent(int, FILE *); static int nextfield(char *); static void skipbl(void); -static int readline(void); +static int readline(FILE *); static void error(const char *, ...) __printf0like(1, 2) __dead2; static char *savestr(const char *); int main(int argc, char *argv[]) { + FILE *infp; + if (argc != 3) error("usage: mknodes file"); - infp = stdin; if ((infp = fopen(argv[1], "r")) == NULL) error("Can't open %s: %s", argv[1], strerror(errno)); - while (readline()) { + while (readline(infp)) { if (line[0] == ' ' || line[0] == '\t') parsefield(); else if (line[0] != '\0') parsenode(); } + fclose(infp); output(argv[2]); exit(0); } static void parsenode(void) { char name[BUFLEN]; char tag[BUFLEN]; struct str *sp; if (curstr && curstr->nfields > 0) curstr->done = 1; nextfield(name); if (! nextfield(tag)) error("Tag expected"); if (*linep != '\0') error("Garbage at end of line"); nodename[ntypes] = savestr(name); for (sp = str ; sp < str + nstr ; sp++) { if (strcmp(sp->tag, tag) == 0) break; } if (sp >= str + nstr) { sp->tag = savestr(tag); sp->nfields = 0; curstr = sp; nstr++; } nodestr[ntypes] = sp; ntypes++; } static void parsefield(void) { char name[BUFLEN]; char type[BUFLEN]; char decl[2 * BUFLEN]; struct field *fp; if (curstr == NULL || curstr->done) error("No current structure to add field to"); if (! nextfield(name)) error("No field name"); if (! nextfield(type)) error("No field type"); fp = &curstr->field[curstr->nfields]; fp->name = savestr(name); if (strcmp(type, "nodeptr") == 0) { fp->type = T_NODE; sprintf(decl, "union node *%s", name); } else if (strcmp(type, "nodelist") == 0) { fp->type = T_NODELIST; sprintf(decl, "struct nodelist *%s", name); } else if (strcmp(type, "string") == 0) { fp->type = T_STRING; sprintf(decl, "char *%s", name); } else if (strcmp(type, "int") == 0) { fp->type = T_INT; sprintf(decl, "int %s", name); } else if (strcmp(type, "other") == 0) { fp->type = T_OTHER; } else if (strcmp(type, "temp") == 0) { fp->type = T_TEMP; } else { error("Unknown type %s", type); } if (fp->type == T_OTHER || fp->type == T_TEMP) { skipbl(); fp->decl = savestr(linep); } else { if (*linep) error("Garbage at end of line"); fp->decl = savestr(decl); } curstr->nfields++; } char writer[] = "\ /*\n\ * This file was generated by the mknodes program.\n\ */\n\ \n"; static void output(char *file) { FILE *hfile; FILE *cfile; FILE *patfile; int i; struct str *sp; struct field *fp; char *p; if ((patfile = fopen(file, "r")) == NULL) error("Can't open %s: %s", file, strerror(errno)); if ((hfile = fopen("nodes.h", "w")) == NULL) error("Can't create nodes.h: %s", strerror(errno)); if ((cfile = fopen("nodes.c", "w")) == NULL) error("Can't create nodes.c"); fputs(writer, hfile); for (i = 0 ; i < ntypes ; i++) fprintf(hfile, "#define %s %d\n", nodename[i], i); fputs("\n\n\n", hfile); for (sp = str ; sp < &str[nstr] ; sp++) { fprintf(hfile, "struct %s {\n", sp->tag); for (i = sp->nfields, fp = sp->field ; --i >= 0 ; fp++) { fprintf(hfile, " %s;\n", fp->decl); } fputs("};\n\n\n", hfile); } fputs("union node {\n", hfile); fprintf(hfile, " int type;\n"); for (sp = str ; sp < &str[nstr] ; sp++) { fprintf(hfile, " struct %s %s;\n", sp->tag, sp->tag); } fputs("};\n\n\n", hfile); fputs("struct nodelist {\n", hfile); fputs("\tstruct nodelist *next;\n", hfile); fputs("\tunion node *n;\n", hfile); fputs("};\n\n\n", hfile); fputs("struct funcdef;\n", hfile); fputs("struct funcdef *copyfunc(union node *);\n", hfile); fputs("union node *getfuncnode(struct funcdef *);\n", hfile); fputs("void reffunc(struct funcdef *);\n", hfile); fputs("void unreffunc(struct funcdef *);\n", hfile); + if (ferror(hfile)) + error("Can't write to nodes.h"); + if (fclose(hfile)) + error("Can't close nodes.h"); fputs(writer, cfile); while (fgets(line, sizeof line, patfile) != NULL) { for (p = line ; *p == ' ' || *p == '\t' ; p++); if (strcmp(p, "%SIZES\n") == 0) outsizes(cfile); else if (strcmp(p, "%CALCSIZE\n") == 0) outfunc(cfile, 1); else if (strcmp(p, "%COPY\n") == 0) outfunc(cfile, 0); else fputs(line, cfile); } + fclose(patfile); + if (ferror(cfile)) + error("Can't write to nodes.c"); + if (fclose(cfile)) + error("Can't close nodes.c"); } static void outsizes(FILE *cfile) { int i; fprintf(cfile, "static const short nodesize[%d] = {\n", ntypes); for (i = 0 ; i < ntypes ; i++) { fprintf(cfile, " ALIGN(sizeof (struct %s)),\n", nodestr[i]->tag); } fprintf(cfile, "};\n"); } static void outfunc(FILE *cfile, int calcsize) { struct str *sp; struct field *fp; int i; fputs(" if (n == NULL)\n", cfile); if (calcsize) fputs(" return;\n", cfile); else fputs(" return NULL;\n", cfile); if (calcsize) fputs(" funcblocksize += nodesize[n->type];\n", cfile); else { fputs(" new = funcblock;\n", cfile); fputs(" funcblock = (char *)funcblock + nodesize[n->type];\n", cfile); } fputs(" switch (n->type) {\n", cfile); for (sp = str ; sp < &str[nstr] ; sp++) { for (i = 0 ; i < ntypes ; i++) { if (nodestr[i] == sp) fprintf(cfile, " case %s:\n", nodename[i]); } for (i = sp->nfields ; --i >= 1 ; ) { fp = &sp->field[i]; switch (fp->type) { case T_NODE: if (calcsize) { indent(12, cfile); fprintf(cfile, "calcsize(n->%s.%s);\n", sp->tag, fp->name); } else { indent(12, cfile); fprintf(cfile, "new->%s.%s = copynode(n->%s.%s);\n", sp->tag, fp->name, sp->tag, fp->name); } break; case T_NODELIST: if (calcsize) { indent(12, cfile); fprintf(cfile, "sizenodelist(n->%s.%s);\n", sp->tag, fp->name); } else { indent(12, cfile); fprintf(cfile, "new->%s.%s = copynodelist(n->%s.%s);\n", sp->tag, fp->name, sp->tag, fp->name); } break; case T_STRING: if (calcsize) { indent(12, cfile); fprintf(cfile, "funcstringsize += strlen(n->%s.%s) + 1;\n", sp->tag, fp->name); } else { indent(12, cfile); fprintf(cfile, "new->%s.%s = nodesavestr(n->%s.%s);\n", sp->tag, fp->name, sp->tag, fp->name); } break; case T_INT: case T_OTHER: if (! calcsize) { indent(12, cfile); fprintf(cfile, "new->%s.%s = n->%s.%s;\n", sp->tag, fp->name, sp->tag, fp->name); } break; } } indent(12, cfile); fputs("break;\n", cfile); } fputs(" };\n", cfile); if (! calcsize) fputs(" new->type = n->type;\n", cfile); } static void indent(int amount, FILE *fp) { while (amount >= 8) { putc('\t', fp); amount -= 8; } while (--amount >= 0) { putc(' ', fp); } } static int nextfield(char *buf) { char *p, *q; p = linep; while (*p == ' ' || *p == '\t') p++; q = buf; while (*p != ' ' && *p != '\t' && *p != '\0') *q++ = *p++; *q = '\0'; linep = p; return (q > buf); } static void skipbl(void) { while (*linep == ' ' || *linep == '\t') linep++; } static int -readline(void) +readline(FILE *infp) { char *p; if (fgets(line, 1024, infp) == NULL) return 0; for (p = line ; *p != '#' && *p != '\n' && *p != '\0' ; p++); while (p > line && (p[-1] == ' ' || p[-1] == '\t')) p--; *p = '\0'; linep = line; linno++; if (p - line > BUFLEN) error("Line too long"); return 1; } static void error(const char *msg, ...) { va_list va; va_start(va, msg); (void) fprintf(stderr, "line %d: ", linno); (void) vfprintf(stderr, msg, va); (void) fputc('\n', stderr); va_end(va); exit(2); } static char * savestr(const char *s) { char *p; if ((p = malloc(strlen(s) + 1)) == NULL) error("Out of space"); (void) strcpy(p, s); return p; } Index: user/ngie/stable-10-libnv/bin/sh/var.c =================================================================== --- user/ngie/stable-10-libnv/bin/sh/var.c (revision 292856) +++ user/ngie/stable-10-libnv/bin/sh/var.c (revision 292857) @@ -1,948 +1,948 @@ /*- * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Kenneth Almquist. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef lint #if 0 static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 5/4/95"; #endif #endif /* not lint */ #include __FBSDID("$FreeBSD$"); #include #include #include /* * Shell variables. */ #include #include #include "shell.h" #include "output.h" #include "expand.h" #include "nodes.h" /* for other headers */ #include "eval.h" /* defines cmdenviron */ #include "exec.h" #include "syntax.h" #include "options.h" #include "mail.h" #include "var.h" #include "memalloc.h" #include "error.h" #include "mystring.h" #include "parser.h" #include "builtins.h" #ifndef NO_HISTORY #include "myhistedit.h" #endif #define VTABSIZE 39 struct varinit { struct var *var; int flags; const char *text; void (*func)(const char *); }; #ifndef NO_HISTORY struct var vhistsize; struct var vterm; #endif struct var vifs; struct var vmail; struct var vmpath; struct var vpath; struct var vps1; struct var vps2; struct var vps4; static struct var voptind; struct var vdisvfork; int forcelocal; static const struct varinit varinit[] = { #ifndef NO_HISTORY { &vhistsize, VUNSET, "HISTSIZE=", sethistsize }, #endif { &vifs, 0, "IFS= \t\n", NULL }, { &vmail, VUNSET, "MAIL=", NULL }, { &vmpath, VUNSET, "MAILPATH=", NULL }, { &vpath, 0, "PATH=" _PATH_DEFPATH, changepath }, /* * vps1 depends on uid */ { &vps2, 0, "PS2=> ", NULL }, { &vps4, 0, "PS4=+ ", NULL }, #ifndef NO_HISTORY { &vterm, VUNSET, "TERM=", setterm }, #endif { &voptind, 0, "OPTIND=1", getoptsreset }, { &vdisvfork, VUNSET, "SH_DISABLE_VFORK=", NULL }, { NULL, 0, NULL, NULL } }; static struct var *vartab[VTABSIZE]; static const char *const locale_names[7] = { "LC_COLLATE", "LC_CTYPE", "LC_MONETARY", "LC_NUMERIC", "LC_TIME", "LC_MESSAGES", NULL }; static const int locale_categories[7] = { LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC, LC_TIME, LC_MESSAGES, 0 }; static int varequal(const char *, const char *); static struct var *find_var(const char *, struct var ***, int *); static int localevar(const char *); extern char **environ; /* * This routine initializes the builtin variables and imports the environment. * It is called when the shell is initialized. */ void initvar(void) { char ppid[20]; const struct varinit *ip; struct var *vp; struct var **vpp; char **envp; for (ip = varinit ; (vp = ip->var) != NULL ; ip++) { if (find_var(ip->text, &vpp, &vp->name_len) != NULL) continue; vp->next = *vpp; *vpp = vp; vp->text = __DECONST(char *, ip->text); vp->flags = ip->flags | VSTRFIXED | VTEXTFIXED; vp->func = ip->func; } /* * PS1 depends on uid */ if (find_var("PS1", &vpp, &vps1.name_len) == NULL) { vps1.next = *vpp; *vpp = &vps1; vps1.text = __DECONST(char *, geteuid() ? "PS1=$ " : "PS1=# "); vps1.flags = VSTRFIXED|VTEXTFIXED; } fmtstr(ppid, sizeof(ppid), "%d", (int)getppid()); setvarsafe("PPID", ppid, 0); for (envp = environ ; *envp ; envp++) { if (strchr(*envp, '=')) { setvareq(*envp, VEXPORT|VTEXTFIXED); } } setvareq("OPTIND=1", VTEXTFIXED); } /* * Safe version of setvar, returns 1 on success 0 on failure. */ int setvarsafe(const char *name, const char *val, int flags) { struct jmploc jmploc; struct jmploc *const savehandler = handler; int err = 0; int inton; inton = is_int_on(); if (setjmp(jmploc.loc)) err = 1; else { handler = &jmploc; setvar(name, val, flags); } handler = savehandler; SETINTON(inton); return err; } /* * Set the value of a variable. The flags argument is stored with the * flags of the variable. If val is NULL, the variable is unset. */ void setvar(const char *name, const char *val, int flags) { const char *p; size_t len; size_t namelen; size_t vallen; char *nameeq; int isbad; isbad = 0; p = name; if (! is_name(*p)) isbad = 1; p++; for (;;) { if (! is_in_name(*p)) { if (*p == '\0' || *p == '=') break; isbad = 1; } p++; } namelen = p - name; if (isbad) error("%.*s: bad variable name", (int)namelen, name); len = namelen + 2; /* 2 is space for '=' and '\0' */ if (val == NULL) { flags |= VUNSET; vallen = 0; } else { vallen = strlen(val); len += vallen; } INTOFF; nameeq = ckmalloc(len); memcpy(nameeq, name, namelen); nameeq[namelen] = '='; if (val) memcpy(nameeq + namelen + 1, val, vallen + 1); else nameeq[namelen + 1] = '\0'; setvareq(nameeq, flags); INTON; } static int localevar(const char *s) { const char *const *ss; if (*s != 'L') return 0; if (varequal(s + 1, "ANG")) return 1; if (strncmp(s + 1, "C_", 2) != 0) return 0; if (varequal(s + 3, "ALL")) return 1; for (ss = locale_names; *ss ; ss++) if (varequal(s + 3, *ss + 3)) return 1; return 0; } /* * Sets/unsets an environment variable from a pointer that may actually be a * pointer into environ where the string should not be manipulated. */ static void change_env(const char *s, int set) { char *eqp; char *ss; INTOFF; ss = savestr(s); if ((eqp = strchr(ss, '=')) != NULL) *eqp = '\0'; if (set && eqp != NULL) (void) setenv(ss, eqp + 1, 1); else (void) unsetenv(ss); ckfree(ss); INTON; return; } /* * Same as setvar except that the variable and value are passed in * the first argument as name=value. Since the first argument will * be actually stored in the table, it should not be a string that * will go away. */ void setvareq(char *s, int flags) { struct var *vp, **vpp; int nlen; if (aflag) flags |= VEXPORT; if (forcelocal && !(flags & (VNOSET | VNOLOCAL))) mklocal(s); vp = find_var(s, &vpp, &nlen); if (vp != NULL) { if (vp->flags & VREADONLY) { if ((flags & (VTEXTFIXED|VSTACK)) == 0) ckfree(s); - error("%.*s: is read only", vp->name_len, s); + error("%.*s: is read only", vp->name_len, vp->text); } if (flags & VNOSET) { if ((flags & (VTEXTFIXED|VSTACK)) == 0) ckfree(s); return; } INTOFF; if (vp->func && (flags & VNOFUNC) == 0) (*vp->func)(s + vp->name_len + 1); if ((vp->flags & (VTEXTFIXED|VSTACK)) == 0) ckfree(vp->text); vp->flags &= ~(VTEXTFIXED|VSTACK|VUNSET); vp->flags |= flags; vp->text = s; /* * We could roll this to a function, to handle it as * a regular variable function callback, but why bother? * * Note: this assumes iflag is not set to 1 initially. * As part of initvar(), this is called before arguments * are looked at. */ if ((vp == &vmpath || (vp == &vmail && ! mpathset())) && iflag == 1) chkmail(1); if ((vp->flags & VEXPORT) && localevar(s)) { change_env(s, 1); (void) setlocale(LC_ALL, ""); updatecharset(); } INTON; return; } /* not found */ if (flags & VNOSET) { if ((flags & (VTEXTFIXED|VSTACK)) == 0) ckfree(s); return; } INTOFF; vp = ckmalloc(sizeof (*vp)); vp->flags = flags; vp->text = s; vp->name_len = nlen; vp->next = *vpp; vp->func = NULL; *vpp = vp; if ((vp->flags & VEXPORT) && localevar(s)) { change_env(s, 1); (void) setlocale(LC_ALL, ""); updatecharset(); } INTON; } /* * Process a linked list of variable assignments. */ void listsetvar(struct strlist *list, int flags) { struct strlist *lp; INTOFF; for (lp = list ; lp ; lp = lp->next) { setvareq(savestr(lp->text), flags); } INTON; } /* * Find the value of a variable. Returns NULL if not set. */ char * lookupvar(const char *name) { struct var *v; v = find_var(name, NULL, NULL); if (v == NULL || v->flags & VUNSET) return NULL; return v->text + v->name_len + 1; } /* * Search the environment of a builtin command. If the second argument * is nonzero, return the value of a variable even if it hasn't been * exported. */ char * bltinlookup(const char *name, int doall) { struct strlist *sp; struct var *v; char *result; result = NULL; for (sp = cmdenviron ; sp ; sp = sp->next) { if (varequal(sp->text, name)) result = strchr(sp->text, '=') + 1; } if (result != NULL) return result; v = find_var(name, NULL, NULL); if (v == NULL || v->flags & VUNSET || (!doall && (v->flags & VEXPORT) == 0)) return NULL; return v->text + v->name_len + 1; } /* * Set up locale for a builtin (LANG/LC_* assignments). */ void bltinsetlocale(void) { struct strlist *lp; int act = 0; char *loc, *locdef; int i; for (lp = cmdenviron ; lp ; lp = lp->next) { if (localevar(lp->text)) { act = 1; break; } } if (!act) return; loc = bltinlookup("LC_ALL", 0); INTOFF; if (loc != NULL) { setlocale(LC_ALL, loc); INTON; updatecharset(); return; } locdef = bltinlookup("LANG", 0); for (i = 0; locale_names[i] != NULL; i++) { loc = bltinlookup(locale_names[i], 0); if (loc == NULL) loc = locdef; if (loc != NULL) setlocale(locale_categories[i], loc); } INTON; updatecharset(); } /* * Undo the effect of bltinlocaleset(). */ void bltinunsetlocale(void) { struct strlist *lp; INTOFF; for (lp = cmdenviron ; lp ; lp = lp->next) { if (localevar(lp->text)) { setlocale(LC_ALL, ""); updatecharset(); return; } } INTON; } /* * Update the localeisutf8 flag. */ void updatecharset(void) { char *charset; charset = nl_langinfo(CODESET); localeisutf8 = !strcmp(charset, "UTF-8"); } void initcharset(void) { updatecharset(); initial_localeisutf8 = localeisutf8; } /* * Generate a list of exported variables. This routine is used to construct * the third argument to execve when executing a program. */ char ** environment(void) { int nenv; struct var **vpp; struct var *vp; char **env, **ep; nenv = 0; for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) { for (vp = *vpp ; vp ; vp = vp->next) if (vp->flags & VEXPORT) nenv++; } ep = env = stalloc((nenv + 1) * sizeof *env); for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) { for (vp = *vpp ; vp ; vp = vp->next) if (vp->flags & VEXPORT) *ep++ = vp->text; } *ep = NULL; return env; } static int var_compare(const void *a, const void *b) { const char *const *sa, *const *sb; sa = a; sb = b; /* * This compares two var=value strings which creates a different * order from what you would probably expect. POSIX is somewhat * ambiguous on what should be sorted exactly. */ return strcoll(*sa, *sb); } /* * Command to list all variables which are set. This is invoked from the * set command when it is called without any options or operands. */ int showvarscmd(int argc __unused, char **argv __unused) { struct var **vpp; struct var *vp; const char *s; const char **vars; int i, n; /* * POSIX requires us to sort the variables. */ n = 0; for (vpp = vartab; vpp < vartab + VTABSIZE; vpp++) { for (vp = *vpp; vp; vp = vp->next) { if (!(vp->flags & VUNSET)) n++; } } INTOFF; vars = ckmalloc(n * sizeof(*vars)); i = 0; for (vpp = vartab; vpp < vartab + VTABSIZE; vpp++) { for (vp = *vpp; vp; vp = vp->next) { if (!(vp->flags & VUNSET)) vars[i++] = vp->text; } } qsort(vars, n, sizeof(*vars), var_compare); for (i = 0; i < n; i++) { /* * Skip improper variable names so the output remains usable as * shell input. */ if (!isassignment(vars[i])) continue; s = strchr(vars[i], '='); s++; outbin(vars[i], s - vars[i], out1); out1qstr(s); out1c('\n'); } ckfree(vars); INTON; return 0; } /* * The export and readonly commands. */ int exportcmd(int argc __unused, char **argv) { struct var **vpp; struct var *vp; char **ap; char *name; char *p; char *cmdname; int ch, values; int flag = argv[0][0] == 'r'? VREADONLY : VEXPORT; cmdname = argv[0]; values = 0; while ((ch = nextopt("p")) != '\0') { switch (ch) { case 'p': values = 1; break; } } if (values && *argptr != NULL) error("-p requires no arguments"); if (*argptr != NULL) { for (ap = argptr; (name = *ap) != NULL; ap++) { if ((p = strchr(name, '=')) != NULL) { p++; } else { vp = find_var(name, NULL, NULL); if (vp != NULL) { vp->flags |= flag; if ((vp->flags & VEXPORT) && localevar(vp->text)) { change_env(vp->text, 1); (void) setlocale(LC_ALL, ""); updatecharset(); } continue; } } setvar(name, p, flag); } } else { for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) { for (vp = *vpp ; vp ; vp = vp->next) { if (vp->flags & flag) { if (values) { /* * Skip improper variable names * so the output remains usable * as shell input. */ if (!isassignment(vp->text)) continue; out1str(cmdname); out1c(' '); } if (values && !(vp->flags & VUNSET)) { outbin(vp->text, vp->name_len + 1, out1); out1qstr(vp->text + vp->name_len + 1); } else outbin(vp->text, vp->name_len, out1); out1c('\n'); } } } } return 0; } /* * The "local" command. */ int localcmd(int argc __unused, char **argv __unused) { char *name; nextopt(""); if (! in_function()) error("Not in a function"); while ((name = *argptr++) != NULL) { mklocal(name); } return 0; } /* * Make a variable a local variable. When a variable is made local, it's * value and flags are saved in a localvar structure. The saved values * will be restored when the shell function returns. We handle the name * "-" as a special case. */ void mklocal(char *name) { struct localvar *lvp; struct var **vpp; struct var *vp; INTOFF; lvp = ckmalloc(sizeof (struct localvar)); if (name[0] == '-' && name[1] == '\0') { lvp->text = ckmalloc(sizeof optlist); memcpy(lvp->text, optlist, sizeof optlist); vp = NULL; } else { vp = find_var(name, &vpp, NULL); if (vp == NULL) { if (strchr(name, '=')) setvareq(savestr(name), VSTRFIXED | VNOLOCAL); else setvar(name, NULL, VSTRFIXED | VNOLOCAL); vp = *vpp; /* the new variable */ lvp->text = NULL; lvp->flags = VUNSET; } else { lvp->text = vp->text; lvp->flags = vp->flags; vp->flags |= VSTRFIXED|VTEXTFIXED; if (name[vp->name_len] == '=') setvareq(savestr(name), VNOLOCAL); } } lvp->vp = vp; lvp->next = localvars; localvars = lvp; INTON; } /* * Called after a function returns. */ void poplocalvars(void) { struct localvar *lvp; struct var *vp; INTOFF; while ((lvp = localvars) != NULL) { localvars = lvp->next; vp = lvp->vp; if (vp == NULL) { /* $- saved */ memcpy(optlist, lvp->text, sizeof optlist); ckfree(lvp->text); optschanged(); } else if ((lvp->flags & (VUNSET|VSTRFIXED)) == VUNSET) { (void)unsetvar(vp->text); } else { if ((vp->flags & VTEXTFIXED) == 0) ckfree(vp->text); vp->flags = lvp->flags; vp->text = lvp->text; } ckfree(lvp); } INTON; } int setvarcmd(int argc, char **argv) { if (argc <= 2) return unsetcmd(argc, argv); else if (argc == 3) setvar(argv[1], argv[2], 0); else error("too many arguments"); return 0; } /* * The unset builtin command. */ int unsetcmd(int argc __unused, char **argv __unused) { char **ap; int i; int flg_func = 0; int flg_var = 0; int ret = 0; while ((i = nextopt("vf")) != '\0') { if (i == 'f') flg_func = 1; else flg_var = 1; } if (flg_func == 0 && flg_var == 0) flg_var = 1; INTOFF; for (ap = argptr; *ap ; ap++) { if (flg_func) ret |= unsetfunc(*ap); if (flg_var) ret |= unsetvar(*ap); } INTON; return ret; } /* * Unset the specified variable. * Called with interrupts off. */ int unsetvar(const char *s) { struct var **vpp; struct var *vp; vp = find_var(s, &vpp, NULL); if (vp == NULL) return (0); if (vp->flags & VREADONLY) return (1); if (vp->text[vp->name_len + 1] != '\0') setvar(s, nullstr, 0); if ((vp->flags & VEXPORT) && localevar(vp->text)) { change_env(s, 0); setlocale(LC_ALL, ""); updatecharset(); } vp->flags &= ~VEXPORT; vp->flags |= VUNSET; if ((vp->flags & VSTRFIXED) == 0) { if ((vp->flags & VTEXTFIXED) == 0) ckfree(vp->text); *vpp = vp->next; ckfree(vp); } return (0); } /* * Returns true if the two strings specify the same variable. The first * variable name is terminated by '='; the second may be terminated by * either '=' or '\0'. */ static int varequal(const char *p, const char *q) { while (*p == *q++) { if (*p++ == '=') return 1; } if (*p == '=' && *(q - 1) == '\0') return 1; return 0; } /* * Search for a variable. * 'name' may be terminated by '=' or a NUL. * vppp is set to the pointer to vp, or the list head if vp isn't found * lenp is set to the number of characters in 'name' */ static struct var * find_var(const char *name, struct var ***vppp, int *lenp) { unsigned int hashval; int len; struct var *vp, **vpp; const char *p = name; hashval = 0; while (*p && *p != '=') hashval = 2 * hashval + (unsigned char)*p++; len = p - name; if (lenp) *lenp = len; vpp = &vartab[hashval % VTABSIZE]; if (vppp) *vppp = vpp; for (vp = *vpp ; vp ; vpp = &vp->next, vp = *vpp) { if (vp->name_len != len) continue; if (memcmp(vp->text, name, len) != 0) continue; if (vppp) *vppp = vpp; return vp; } return NULL; } Index: user/ngie/stable-10-libnv/contrib/netbsd-tests/lib/libc/gen/t_assert.c =================================================================== --- user/ngie/stable-10-libnv/contrib/netbsd-tests/lib/libc/gen/t_assert.c (revision 292856) +++ user/ngie/stable-10-libnv/contrib/netbsd-tests/lib/libc/gen/t_assert.c (revision 292857) @@ -1,132 +1,155 @@ /* $NetBSD: t_assert.c,v 1.2 2011/06/14 05:28:00 jruoho Exp $ */ /*- * Copyright (c) 2011 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by Jukka Ruohonen. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include __RCSID("$NetBSD: t_assert.c,v 1.2 2011/06/14 05:28:00 jruoho Exp $"); #include #include #include #include #include #include #include +#ifdef __FreeBSD__ +#include +#include +#include + +static void +disable_corefile(void) +{ + struct rlimit limits; + + limits.rlim_cur = 0; + limits.rlim_max = 0; + + ATF_REQUIRE(setrlimit(RLIMIT_CORE, &limits) == 0); +} +#endif + static void handler(int); static void handler(int signo) { /* Nothing. */ } ATF_TC(assert_false); ATF_TC_HEAD(assert_false, tc) { atf_tc_set_md_var(tc, "descr", "Test that assert(3) works, #1"); } ATF_TC_BODY(assert_false, tc) { struct sigaction sa; pid_t pid; int sta; pid = fork(); ATF_REQUIRE(pid >= 0); if (pid == 0) { +#ifdef __FreeBSD__ + disable_corefile(); +#endif (void)closefrom(0); (void)memset(&sa, 0, sizeof(struct sigaction)); sa.sa_flags = 0; sa.sa_handler = handler; (void)sigemptyset(&sa.sa_mask); (void)sigaction(SIGABRT, &sa, 0); assert(1 == 1); _exit(EXIT_SUCCESS); } (void)wait(&sta); if (WIFSIGNALED(sta) != 0 || WIFEXITED(sta) == 0) atf_tc_fail("assert(3) fired haphazardly"); } ATF_TC(assert_true); ATF_TC_HEAD(assert_true, tc) { atf_tc_set_md_var(tc, "descr", "Test that assert(3) works, #2"); } ATF_TC_BODY(assert_true, tc) { struct sigaction sa; pid_t pid; int sta; pid = fork(); ATF_REQUIRE(pid >= 0); if (pid == 0) { +#ifdef __FreeBSD__ + disable_corefile(); +#endif (void)closefrom(0); (void)memset(&sa, 0, sizeof(struct sigaction)); sa.sa_flags = 0; sa.sa_handler = handler; (void)sigemptyset(&sa.sa_mask); (void)sigaction(SIGABRT, &sa, 0); assert(1 == 2); _exit(EXIT_SUCCESS); } (void)wait(&sta); if (WIFSIGNALED(sta) == 0 || WTERMSIG(sta) != SIGABRT) atf_tc_fail("assert(3) did not fire"); } ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, assert_false); ATF_TP_ADD_TC(tp, assert_true); return atf_no_error(); } Index: user/ngie/stable-10-libnv/contrib/netbsd-tests/lib/libc/ssp/t_ssp.sh =================================================================== --- user/ngie/stable-10-libnv/contrib/netbsd-tests/lib/libc/ssp/t_ssp.sh (revision 292856) +++ user/ngie/stable-10-libnv/contrib/netbsd-tests/lib/libc/ssp/t_ssp.sh (revision 292857) @@ -1,459 +1,460 @@ # $NetBSD: t_ssp.sh,v 1.7 2014/04/06 19:28:59 christos Exp $ # # Copyright (c) 2008 The NetBSD Foundation, Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. # h_pass() { echo "Executing command [ $2$1 ]" eval $2 atf_check -s exit:0 -o ignore -e ignore $1 } h_fail() { echo "Executing command [ $2$1 ]" # Begin FreeBSD + ulimit -c 0 if true; then eval $2 atf_check -s signal -o ignore -e ignore $1 else # End FreeBSD eval $2 atf_check -s signal:6 -o ignore -e ignore $1 # Begin FreeBSD fi # End FreeBSD } atf_test_case sprintf sprintf_head() { atf_set "descr" "Checks sprintf(3)" } sprintf_body() { prog="$(atf_get_srcdir)/h_sprintf" h_pass "$prog ok" # Begin FreeBSD if true; then h_fail "$prog 0123456789ab" else # End FreeBSD h_fail "$prog 0123456789" # Begin FreeBSD fi # End FreeBSD } atf_test_case vsprintf vsprintf_head() { atf_set "descr" "Checks vsprintf(3)" } vsprintf_body() { prog="$(atf_get_srcdir)/h_vsprintf" h_pass "$prog ok" # Begin FreeBSD if true; then h_fail "$prog 0123456789ab" else # End FreeBSD h_fail "$prog 0123456789" # Begin FreeBSD fi # End FreeBSD } atf_test_case snprintf snprintf_head() { atf_set "descr" "Checks snprintf(3)" } snprintf_body() { prog="$(atf_get_srcdir)/h_snprintf" h_pass "$prog 10" # Begin FreeBSD if true; then h_fail "$prog 13" else # End FreeBSD h_fail "$prog 11" # Begin FreeBSD fi # End FreeBSD } atf_test_case vsnprintf vsnprintf_head() { atf_set "descr" "Checks vsnprintf(3)" } vsnprintf_body() { prog="$(atf_get_srcdir)/h_vsnprintf" h_pass "$prog 10" # Begin FreeBSD if true; then h_fail "$prog 13" else # End FreeBSD h_fail "$prog 11" # Begin FreeBSD fi # End FreeBSD } atf_test_case gets gets_head() { atf_set "descr" "Checks gets(3)" } gets_body() { prog="$(atf_get_srcdir)/h_gets" h_pass "$prog" "echo ok |" # Begin FreeBSD if true; then h_fail "$prog" "echo 0123456789ab |" else # End FreeBSD h_fail "$prog" "echo 0123456789 |" # Begin FreeBSD fi # End FreeBSD } atf_test_case fgets fgets_head() { atf_set "descr" "Checks fgets(3)" } fgets_body() { prog="$(atf_get_srcdir)/h_fgets" h_pass "$prog 10" "echo ok |" # Begin FreeBSD if true; then h_fail "$prog 13" "echo 0123456789abc |" else # End FreeBSD h_fail "$prog 11" "echo busted |" # Begin FreeBSD fi # End FreeBSD } atf_test_case memcpy memcpy_head() { atf_set "descr" "Checks memcpy(3)" } memcpy_body() { prog="$(atf_get_srcdir)/h_memcpy" h_pass "$prog 10" # Begin FreeBSD if true; then h_fail "$prog 13" else # End FreeBSD h_fail "$prog 11" # Begin FreeBSD fi # End FreeBSD } atf_test_case memmove memmove_head() { atf_set "descr" "Checks memmove(3)" } memmove_body() { prog="$(atf_get_srcdir)/h_memmove" h_pass "$prog 10" # Begin FreeBSD if true; then h_fail "$prog 13" else # End FreeBSD h_fail "$prog 11" # Begin FreeBSD fi # End FreeBSD } atf_test_case memset memset_head() { atf_set "descr" "Checks memset(3)" } memset_body() { prog="$(atf_get_srcdir)/h_memset" h_pass "$prog 10" # Begin FreeBSD if true; then h_fail "$prog 13" else # End FreeBSD h_fail "$prog 11" # Begin FreeBSD fi # End FreeBSD } atf_test_case strcpy strcpy_head() { atf_set "descr" "Checks strcpy(3)" } strcpy_body() { prog="$(atf_get_srcdir)/h_strcpy" h_pass "$prog 0123456" # Begin FreeBSD if true; then h_fail "$prog 0123456789ab" else # End FreeBSD h_fail "$prog 0123456789" # Begin FreeBSD fi # End FreeBSD } atf_test_case stpcpy stpcpy_head() { atf_set "descr" "Checks stpcpy(3)" } stpcpy_body() { prog="$(atf_get_srcdir)/h_stpcpy" h_pass "$prog 0123456" # Begin FreeBSD if true; then h_fail "$prog 0123456789ab" else # End FreeBSD h_fail "$prog 0123456789" # Begin FreeBSD fi # End FreeBSD } atf_test_case strcat strcat_head() { atf_set "descr" "Checks strcat(3)" } strcat_body() { prog="$(atf_get_srcdir)/h_strcat" h_pass "$prog 0123456" h_fail "$prog 0123456789ABCDEF" } atf_test_case strncpy strncpy_head() { atf_set "descr" "Checks strncpy(3)" } strncpy_body() { prog="$(atf_get_srcdir)/h_strncpy" h_pass "$prog 10" # Begin FreeBSD if true; then h_fail "$prog 13" else # End FreeBSD h_fail "$prog 11" # Begin FreeBSD fi # End FreeBSD } atf_test_case stpncpy stpncpy_head() { atf_set "descr" "Checks stpncpy(3)" } stpncpy_body() { prog="$(atf_get_srcdir)/h_stpncpy" h_pass "$prog 10" # Begin FreeBSD if true; then h_fail "$prog 13" else # End FreeBSD h_fail "$prog 11" # Begin FreeBSD fi # End FreeBSD } atf_test_case strncat strncat_head() { atf_set "descr" "Checks strncat(3)" } strncat_body() { prog="$(atf_get_srcdir)/h_strncat" # Begin FreeBSD h_pass "$prog 8" if true; then h_fail "$prog 11" else # End FreeBSD h_fail "$prog 9" # Begin FreeBSD fi # End FreeBSD } atf_test_case raw raw_head() { atf_set "descr" "Checks raw array overflow" } raw_body() { prog="$(atf_get_srcdir)/h_raw" h_pass "$prog 9" # Begin FreeBSD if true; then h_fail "$prog 12" else # End FreeBSD h_fail "$prog 10" # Begin FreeBSD fi # End FreeBSD } atf_test_case read read_head() { atf_set "descr" "Checks read(2)" } read_body() { prog="$(atf_get_srcdir)/h_read" h_pass "$prog 1024" "echo foo |" # Begin FreeBSD if true; then h_fail "$prog 1027" "echo bar |" else # End FreeBSD h_fail "$prog 1025" "echo bar |" # Begin FreeBSD fi # End FreeBSD } atf_test_case readlink readlink_head() { atf_set "descr" "Checks readlink(2)" } readlink_body() { prog="$(atf_get_srcdir)/h_readlink" # Begin FreeBSD if true; then h_pass "$prog 512" h_fail "$prog 523" else # End FreeBSD h_pass "$prog 1024" h_fail "$prog 1025" # Begin FreeBSD fi # End FreeBSD } atf_test_case getcwd getcwd_head() { atf_set "descr" "Checks getcwd(3)" } getcwd_body() { prog="$(atf_get_srcdir)/h_getcwd" h_pass "$prog 1024" # Begin FreeBSD if false; then # End FreeBSD h_fail "$prog 1025" # Begin FreeBSD fi # End FreeBSD } atf_init_test_cases() { atf_add_test_case sprintf atf_add_test_case vsprintf atf_add_test_case snprintf atf_add_test_case vsnprintf atf_add_test_case gets atf_add_test_case fgets atf_add_test_case memcpy atf_add_test_case memmove atf_add_test_case memset atf_add_test_case stpcpy atf_add_test_case stpncpy atf_add_test_case strcat atf_add_test_case strcpy atf_add_test_case strncat atf_add_test_case strncpy atf_add_test_case raw atf_add_test_case read atf_add_test_case readlink atf_add_test_case getcwd } Index: user/ngie/stable-10-libnv/contrib/netbsd-tests/usr.bin/grep/d_binary.out =================================================================== --- user/ngie/stable-10-libnv/contrib/netbsd-tests/usr.bin/grep/d_binary.out (revision 292856) +++ user/ngie/stable-10-libnv/contrib/netbsd-tests/usr.bin/grep/d_binary.out (revision 292857) @@ -1 +1 @@ -Binary file /bin/sh matches +Binary file test.file matches Index: user/ngie/stable-10-libnv/contrib/netbsd-tests/usr.bin/grep/t_grep.sh =================================================================== --- user/ngie/stable-10-libnv/contrib/netbsd-tests/usr.bin/grep/t_grep.sh (revision 292856) +++ user/ngie/stable-10-libnv/contrib/netbsd-tests/usr.bin/grep/t_grep.sh (revision 292857) @@ -1,246 +1,259 @@ # $NetBSD: t_grep.sh,v 1.2 2013/05/17 15:39:17 christos Exp $ # # Copyright (c) 2008, 2009 The NetBSD Foundation, Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. # atf_test_case basic basic_head() { atf_set "descr" "Checks basic functionality" } basic_body() { atf_check -o file:"$(atf_get_srcdir)/d_basic.out" -x \ 'jot 10000 | grep 123' } atf_test_case binary binary_head() { atf_set "descr" "Checks handling of binary files" } binary_body() { + # Begin FreeBSD + # + # Generate stable output instead of depending on uname to match the + # branded OS name of /bin/sh + if true; then + dd if=/dev/zero count=1 of=test.file + echo -n "foobar" >> test.file + atf_check -o file:"$(atf_get_srcdir)/d_binary.out" grep foobar test.file + else + # End FreeBSD atf_check -o file:"$(atf_get_srcdir)/d_binary.out" grep $(uname) /bin/sh + # Begin FreeBSD + fi + # End FreeBSD } atf_test_case recurse recurse_head() { atf_set "descr" "Checks recursive searching" } recurse_body() { mkdir -p recurse/a/f recurse/d echo -e "cod\ndover sole\nhaddock\nhalibut\npilchard" > recurse/d/fish echo -e "cod\nhaddock\nplaice" > recurse/a/f/favourite-fish atf_check -o file:"$(atf_get_srcdir)/d_recurse.out" grep -r haddock recurse } atf_test_case recurse_symlink recurse_symlink_head() { atf_set "descr" "Checks symbolic link recursion" } recurse_symlink_body() { mkdir -p test/c/d (cd test/c/d && ln -s ../d .) echo "Test string" > test/c/match atf_check -o file:"$(atf_get_srcdir)/d_recurse_symlink.out" \ -e file:"$(atf_get_srcdir)/d_recurse_symlink.err" \ grep -r string test } atf_test_case word_regexps word_regexps_head() { atf_set "descr" "Checks word-regexps" } word_regexps_body() { atf_check -o file:"$(atf_get_srcdir)/d_word_regexps.out" \ grep -w separated $(atf_get_srcdir)/d_input } atf_test_case begin_end begin_end_head() { atf_set "descr" "Checks handling of line beginnings and ends" } begin_end_body() { atf_check -o file:"$(atf_get_srcdir)/d_begin_end_a.out" \ grep ^Front "$(atf_get_srcdir)/d_input" atf_check -o file:"$(atf_get_srcdir)/d_begin_end_b.out" \ grep ending$ "$(atf_get_srcdir)/d_input" } atf_test_case ignore_case ignore_case_head() { atf_set "descr" "Checks ignore-case option" } ignore_case_body() { atf_check -o file:"$(atf_get_srcdir)/d_ignore_case.out" \ grep -i Upper "$(atf_get_srcdir)/d_input" } atf_test_case invert invert_head() { atf_set "descr" "Checks selecting non-matching lines with -v option" } invert_body() { atf_check -o file:"$(atf_get_srcdir)/d_invert.out" \ grep -v fish "$(atf_get_srcdir)/d_invert.in" } atf_test_case whole_line whole_line_head() { atf_set "descr" "Checks whole-line matching with -x flag" } whole_line_body() { atf_check -o file:"$(atf_get_srcdir)/d_whole_line.out" \ grep -x matchme "$(atf_get_srcdir)/d_input" } atf_test_case negative negative_head() { atf_set "descr" "Checks handling of files with no matches" } negative_body() { atf_check -s ne:0 grep "not a hope in hell" "$(atf_get_srcdir)/d_input" } atf_test_case context context_head() { atf_set "descr" "Checks displaying context with -A, -B and -C flags" } context_body() { cp $(atf_get_srcdir)/d_context_*.* . atf_check -o file:d_context_a.out grep -C2 bamboo d_context_a.in atf_check -o file:d_context_b.out grep -A3 tilt d_context_a.in atf_check -o file:d_context_c.out grep -B4 Whig d_context_a.in atf_check -o file:d_context_d.out grep -C1 pig d_context_a.in d_context_b.in } atf_test_case file_exp file_exp_head() { atf_set "descr" "Checks reading expressions from file" } file_exp_body() { atf_check -o file:"$(atf_get_srcdir)/d_file_exp.out" -x \ 'jot 21 -1 1.00 | grep -f '"$(atf_get_srcdir)"'/d_file_exp.in' } atf_test_case egrep egrep_head() { atf_set "descr" "Checks matching special characters with egrep" } egrep_body() { atf_check -o file:"$(atf_get_srcdir)/d_egrep.out" \ egrep '\?|\*$$' "$(atf_get_srcdir)/d_input" } atf_test_case zgrep zgrep_head() { atf_set "descr" "Checks handling of gzipped files with zgrep" } zgrep_body() { cp "$(atf_get_srcdir)/d_input" . gzip d_input || atf_fail "gzip failed" atf_check -o file:"$(atf_get_srcdir)/d_zgrep.out" zgrep -h line d_input.gz } atf_test_case nonexistent nonexistent_head() { atf_set "descr" "Checks that -s flag suppresses error" \ "messages about nonexistent files" } nonexistent_body() { atf_check -s ne:0 grep -s foobar nonexistent } atf_test_case context2 context2_head() { atf_set "descr" "Checks displaying context with -z flag" } context2_body() { printf "haddock\000cod\000plaice\000" > test1 printf "mackeral\000cod\000crab\000" > test2 atf_check -o file:"$(atf_get_srcdir)/d_context2_a.out" \ grep -z -A1 cod test1 test2 atf_check -o file:"$(atf_get_srcdir)/d_context2_b.out" \ grep -z -B1 cod test1 test2 atf_check -o file:"$(atf_get_srcdir)/d_context2_c.out" \ grep -z -C1 cod test1 test2 } atf_init_test_cases() { atf_add_test_case basic atf_add_test_case binary atf_add_test_case recurse atf_add_test_case recurse_symlink atf_add_test_case word_regexps atf_add_test_case begin_end atf_add_test_case ignore_case atf_add_test_case invert atf_add_test_case whole_line atf_add_test_case negative atf_add_test_case context atf_add_test_case file_exp atf_add_test_case egrep atf_add_test_case zgrep atf_add_test_case nonexistent atf_add_test_case context2 } Index: user/ngie/stable-10-libnv/contrib/smbfs/README =================================================================== --- user/ngie/stable-10-libnv/contrib/smbfs/README (revision 292856) +++ user/ngie/stable-10-libnv/contrib/smbfs/README (revision 292857) @@ -1,53 +1,53 @@ SMB/CIFS protocol and SMB/CIFS file system implementation for FreeBSD, version 1.4. This is native SMB/CIFS filesystem (smbfs for short) for FreeBSD. It is a complete, kernel side implementation of SMB requester and filesystem. Supported platform Comment FreeBSD 4.X Port FreeBSD 4.5 Everything available in the base system. FreeBSD-current Everything available in the base system. Darwin maintained in the Darwin's tree. - I'm would be very grateful for any feedback, bug reports etc. + I would be very grateful for any feedback, bug reports etc. Supported SMB servers: Samba Windows 95/98/ME/2000/NT4.0 (SPs 4, 5, 6) IBM LanManager NetApp - An updated versions of this package can be retrieved from ftp server: + An updated version of this package can be retrieved from ftp server: ftp://ftp.butya.kz/pub/smbfs/smbfs.tar.gz - Perfomance + Performance ========== - There is some perfomance benchmarks over 10Mbit network: + These are some performance benchmarks over a 10Mbit network: Win95 machine as server: IOZONE: auto-test mode MB reclen bytes/sec written bytes/sec read 1 512 339791 323416 1 1024 481067 431568 1 2048 648394 588674 1 4096 630130 583555 1 8192 671088 618514 Samba 2.0.6 as server: IOZONE: auto-test mode MB reclen bytes/sec written bytes/sec read 1 512 409200 437191 1 1024 545600 596523 1 2048 729444 798915 1 4096 871543 919299 1 8192 900790 1024562 Author: Boris Popov Index: user/ngie/stable-10-libnv/etc/defaults/periodic.conf =================================================================== --- user/ngie/stable-10-libnv/etc/defaults/periodic.conf (revision 292856) +++ user/ngie/stable-10-libnv/etc/defaults/periodic.conf (revision 292857) @@ -1,394 +1,394 @@ #!/bin/sh # # This is defaults/periodic.conf - a file full of useful variables that # you can set to change the default behaviour of periodic jobs on your # system. You should not edit this file! Put any overrides into one of the # $periodic_conf_files instead and you will be able to update these defaults # later without spamming your local configuration information. # # The $periodic_conf_files files should only contain values which override # values set in this file. This eases the upgrade path when defaults # are changed and new features are added. # # For a more detailed explanation of all the periodic.conf variables, please # refer to the periodic.conf(5) manual page. # # $FreeBSD$ # # What files override these defaults ? periodic_conf_files="/etc/periodic.conf /etc/periodic.conf.local" # periodic script dirs local_periodic="/usr/local/etc/periodic" # Daily options # These options are used by periodic(8) itself to determine what to do # with the output of the sub-programs that are run, and where to send # that output. $daily_output might be set to /var/log/daily.log if you # wish to log the daily output and have the files rotated by newsyslog(8) # daily_output="root" # user or /file daily_show_success="YES" # scripts returning 0 daily_show_info="YES" # scripts returning 1 daily_show_badconfig="NO" # scripts returning 2 # 100.clean-disks daily_clean_disks_enable="NO" # Delete files daily daily_clean_disks_files="[#,]* .#* a.out *.core *.CKP .emacs_[0-9]*" daily_clean_disks_days=3 # If older than this daily_clean_disks_verbose="YES" # Mention files deleted # 110.clean-tmps daily_clean_tmps_enable="NO" # Delete stuff daily daily_clean_tmps_dirs="/tmp" # Delete under here daily_clean_tmps_days="3" # If not accessed for daily_clean_tmps_ignore=".X*-lock .X11-unix .ICE-unix .font-unix .XIM-unix" daily_clean_tmps_ignore="$daily_clean_tmps_ignore quota.user quota.group .snap" daily_clean_tmps_ignore="$daily_clean_tmps_ignore .sujournal" # Don't delete these daily_clean_tmps_verbose="YES" # Mention files deleted # 120.clean-preserve daily_clean_preserve_enable="YES" # Delete files daily daily_clean_preserve_days=7 # If not modified for daily_clean_preserve_verbose="YES" # Mention files deleted # 130.clean-msgs daily_clean_msgs_enable="YES" # Delete msgs daily daily_clean_msgs_days= # If not modified for # 140.clean-rwho daily_clean_rwho_enable="YES" # Delete rwho daily daily_clean_rwho_days=7 # If not modified for daily_clean_rwho_verbose="YES" # Mention files deleted # 150.clean-hoststat daily_clean_hoststat_enable="YES" # Purge sendmail host # status cache daily # 200.backup-passwd daily_backup_passwd_enable="YES" # Backup passwd & group # 210.backup-aliases daily_backup_aliases_enable="YES" # Backup mail aliases # 220.backup-pkgdb daily_backup_pkgdb_enable="YES" # Backup /var/db/pkg daily_backup_pkgdb_dir="/var/backups" # 300.calendar daily_calendar_enable="NO" # Run calendar -a # 310.accounting daily_accounting_enable="YES" # Rotate acct files daily_accounting_compress="NO" # Gzip rotated files daily_accounting_flags=-q # Flags to /usr/sbin/sa daily_accounting_save=3 # How many files to save # 330.news daily_news_expire_enable="YES" # Run news.expire # 400.status-disks daily_status_disks_enable="YES" # Check disk status daily_status_disks_df_flags="-l -h" # df(1) flags for check # 401.status-graid daily_status_graid_enable="NO" # Check graid(8) # 404.status-zfs daily_status_zfs_enable="NO" # Check ZFS daily_status_zfs_zpool_list_enable="YES" # List ZFS pools # 406.status-gmirror daily_status_gmirror_enable="NO" # Check gmirror(8) # 407.status-graid3 daily_status_graid3_enable="NO" # Check graid3(8) # 408.status-gstripe daily_status_gstripe_enable="NO" # Check gstripe(8) # 409.status-gconcat daily_status_gconcat_enable="NO" # Check gconcat(8) # 420.status-network daily_status_network_enable="YES" # Check network status daily_status_network_usedns="YES" # DNS lookups are ok daily_status_network_netstat_flags="-d" # netstat(1) flags # 430.status-rwho daily_status_rwho_enable="YES" # Check system status # 440.status-mailq daily_status_mailq_enable="YES" # Check mail status daily_status_mailq_shorten="NO" # Shorten output daily_status_include_submit_mailq="YES" # Also submit queue # 450.status-security daily_status_security_enable="YES" # Security check # See also "Security options" below for more options daily_status_security_inline="NO" # Run inline ? daily_status_security_output="root" # user or /file # 460.status-mail-rejects daily_status_mail_rejects_enable="YES" # Check mail rejects daily_status_mail_rejects_logs=3 # How many logs to check daily_status_mail_rejects_shorten="NO" # Shorten output # 480.status-ntpd daily_status_ntpd_enable="NO" # Check NTP status # 500.queuerun daily_queuerun_enable="YES" # Run mail queue daily_submit_queuerun="YES" # Also submit queue # 510.status-world-kernel daily_status_world_kernel="YES" # Check the running # userland/kernel version # 800.scrub-zfs daily_scrub_zfs_enable="NO" daily_scrub_zfs_pools="" # empty string selects all pools daily_scrub_zfs_default_threshold="35" # days between scrubs #daily_scrub_zfs_${poolname}_threshold="35" # pool specific threshold # 999.local daily_local="/etc/daily.local" # Local scripts # Weekly options # These options are used by periodic(8) itself to determine what to do # with the output of the sub-programs that are run, and where to send # that output. $weekly_output might be set to /var/log/weekly.log if you # wish to log the weekly output and have the files rotated by newsyslog(8) # weekly_output="root" # user or /file weekly_show_success="YES" # scripts returning 0 weekly_show_info="YES" # scripts returning 1 weekly_show_badconfig="NO" # scripts returning 2 # 310.locate weekly_locate_enable="YES" # Update locate weekly # 320.whatis weekly_whatis_enable="YES" # Update whatis weekly # 330.catman weekly_catman_enable="NO" # Preformat man pages # 340.noid weekly_noid_enable="NO" # Find unowned files weekly_noid_dirs="/" # Look here # 450.status-security weekly_status_security_enable="YES" # Security check # See also "Security options" above for more options weekly_status_security_inline="NO" # Run inline ? weekly_status_security_output="root" # user or /file # 999.local weekly_local="/etc/weekly.local" # Local scripts # Monthly options # These options are used by periodic(8) itself to determine what to do # with the output of the sub-programs that are run, and where to send # that output. $monthly_output might be set to /var/log/monthly.log if you # wish to log the monthly output and have the files rotated by newsyslog(8) # monthly_output="root" # user or /file monthly_show_success="YES" # scripts returning 0 monthly_show_info="YES" # scripts returning 1 monthly_show_badconfig="NO" # scripts returning 2 # 200.accounting monthly_accounting_enable="YES" # Login accounting # 450.status-security monthly_status_security_enable="YES" # Security check # See also "Security options" above for more options monthly_status_security_inline="NO" # Run inline ? monthly_status_security_output="root" # user or /file # 999.local monthly_local="/etc/monthly.local" # Local scripts # Security options # These options are used by the security periodic(8) scripts spawned in # daily and weekly 450.status-security. security_status_logdir="/var/log" # Directory for logs security_status_diff_flags="-b -u" # flags for diff output # Each of the security_status_*_period options below can have one of the # following values: # - NO: do not run at all # - daily: only run during the daily security status # - weekly: only run during the weekly security status # - monthly: only run during the monthly security status # Note that if periodic security scripts are run from crontab(5) directly, # they will be run unless _enable or _period is set to "NO". # 100.chksetuid security_status_chksetuid_enable="YES" security_status_chksetuid_period="daily" # 110.neggrpperm security_status_neggrpperm_enable="YES" security_status_neggrpperm_period="daily" # 200.chkmounts security_status_chkmounts_enable="YES" security_status_chkmounts_period="daily" #security_status_chkmounts_ignore="^amd:" # Don't check matching # FS types security_status_noamd="NO" # Don't check amd mounts # 300.chkuid0 security_status_chkuid0_enable="YES" security_status_chkuid0_period="daily" # 400.passwdless security_status_passwdless_enable="YES" security_status_passwdless_period="daily" # 410.logincheck security_status_logincheck_enable="YES" security_status_logincheck_period="daily" # 460.chkportsum security_status_chkportsum_enable="NO" # Check ports w/ wrong checksum security_status_chkportsum_period="daily" # 500.ipfwdenied security_status_ipfwdenied_enable="YES" security_status_ipfwdenied_period="daily" # 510.ipfdenied security_status_ipfdenied_enable="YES" security_status_ipfdenied_period="daily" # 520.pfdenied security_status_pfdenied_enable="YES" security_status_pfdenied_period="daily" # 550.ipfwlimit security_status_ipfwlimit_enable="YES" security_status_ipfwlimit_period="daily" # 610.ipf6denied security_status_ipf6denied_enable="YES" security_status_ipf6denied_period="daily" # 700.kernelmsg security_status_kernelmsg_enable="YES" security_status_kernelmsg_period="daily" # 800.loginfail security_status_loginfail_enable="YES" security_status_loginfail_period="daily" # 900.tcpwrap security_status_tcpwrap_enable="YES" security_status_tcpwrap_period="daily" # Define source_periodic_confs, the mechanism used by /etc/periodic/*/* # scripts to source defaults/periodic.conf overrides safely. if [ -z "${source_periodic_confs_defined}" ]; then source_periodic_confs_defined=yes # Compatibility with old daily variable names. # They can be removed in stable/11. security_daily_compat_var() { local var=$1 dailyvar value dailyvar=daily_status_security${var#security_status} periodvar=${var%enable}period eval value=\"\$$dailyvar\" [ -z "$value" ] && return echo "Warning: Variable \$$dailyvar is deprecated," \ "use \$$var instead." >&2 case "$value" in [Yy][Ee][Ss]) - $var=YES - $periodvar=daily + eval $var=YES + eval $periodvar=daily ;; *) eval $var=\"$value\" ;; esac } check_yesno_period() { local var="$1" periodvar value period eval value=\"\$$var\" case "$value" in [Yy][Ee][Ss]) ;; *) return 1 ;; esac periodvar=${var%enable}period eval period=\"\$$periodvar\" case "$PERIODIC" in "security daily") case "$period" in [Dd][Aa][Ii][Ll][Yy]) return 0 ;; *) return 1 ;; esac ;; "security weekly") case "$period" in [Ww][Ee][Ee][Kk][Ll][Yy]) return 0 ;; *) return 1 ;; esac ;; "security monthly") case "$period" in [Mm][Oo][Nn][Tt][Hh][Ll][Yy]) return 0 ;; *) return 1 ;; esac ;; security) # Run directly from crontab(5). case "$period" in [Nn][Oo]) return 1 ;; *) return 0 ;; esac ;; '') # Script run manually. return 0 ;; *) echo "ASSERTION FAILED: Unexpected value for" \ "\$PERIODIC: '$PERIODIC'" >&2 exit 127 ;; esac } source_periodic_confs() { local i sourced_files for i in ${periodic_conf_files}; do case ${sourced_files} in *:$i:*) ;; *) sourced_files="${sourced_files}:$i:" [ -r $i ] && . $i ;; esac done } fi Index: user/ngie/stable-10-libnv/etc/mtree/BSD.tests.dist =================================================================== --- user/ngie/stable-10-libnv/etc/mtree/BSD.tests.dist (revision 292856) +++ user/ngie/stable-10-libnv/etc/mtree/BSD.tests.dist (revision 292857) @@ -1,435 +1,439 @@ # $FreeBSD$ # # Please see the file src/etc/mtree/README before making changes to this file. # /set type=dir uname=root gname=wheel mode=0755 . bin cat .. chown .. date .. dd .. expr .. ls .. mv .. pax .. pkill .. sh builtins .. errors .. execution .. expansion .. parameters .. parser .. set-e .. .. sleep .. test .. .. cddl lib .. sbin .. usr.bin .. usr.sbin .. .. etc rc.d .. .. games .. gnu lib .. usr.bin diff .. .. .. lib atf libatf-c detail .. .. libatf-c++ detail .. .. test-programs .. .. libarchive .. libc c063 .. db .. gen execve .. posix_spawn .. .. hash data .. .. inet .. locale .. net getaddrinfo data .. .. .. + nss + .. regex data .. + .. + resolv .. rpc .. ssp .. stdio .. stdlib .. string .. sys .. time .. tls dso .. .. termios .. ttyio .. .. libcrypt .. libmp .. libnv .. librt .. libthr dlopen .. .. libutil .. msun .. .. libexec atf atf-check .. atf-sh .. .. .. sbin dhclient .. devd .. growfs .. mdconfig .. .. secure lib .. libexec .. usr.bin .. usr.sbin .. .. share examples tests atf .. plain .. .. .. .. sys acl .. aio .. fifo .. file .. kern acct .. execve .. pipe .. kqueue .. mqueue .. netinet .. pjdfstest chflags .. chmod .. chown .. ftruncate .. granular .. link .. mkdir .. mkfifo .. mknod .. open .. rename .. rmdir .. symlink .. truncate .. unlink .. .. posixshm .. vfs .. vm .. .. usr.bin apply .. basename .. bmake archives fmt_44bsd .. fmt_44bsd_mod .. fmt_oldbsd .. .. basic t0 .. t1 .. t2 .. t3 .. .. execution ellipsis .. empty .. joberr .. plus .. .. shell builtin .. meta .. path .. path_select .. replace .. select .. .. suffixes basic .. src_wild1 .. src_wild2 .. .. syntax directive-t0 .. enl .. funny-targets .. semi .. .. sysmk t0 2 1 .. .. mk .. .. t1 2 1 .. .. mk .. .. t2 2 1 .. .. mk .. .. .. variables modifier_M .. modifier_t .. opt_V .. t0 .. .. .. calendar .. cmp .. cpio .. col .. comm .. cut .. dirname .. file2c .. grep .. gzip .. join .. jot .. lastcomm .. limits .. m4 .. ncal .. opensm .. printf .. sed regress.multitest.out .. .. tar .. timeout .. tr .. truncate .. uudecode .. uuencode .. xargs .. yacc yacc .. .. .. usr.sbin etcupdate .. fstyp .. makefs .. newsyslog .. nmtree .. pw .. sa .. .. .. # vim: set expandtab ts=4 sw=4: Index: user/ngie/stable-10-libnv/etc/periodic/daily/800.scrub-zfs =================================================================== --- user/ngie/stable-10-libnv/etc/periodic/daily/800.scrub-zfs (revision 292856) +++ user/ngie/stable-10-libnv/etc/periodic/daily/800.scrub-zfs (revision 292857) @@ -1,98 +1,102 @@ #!/bin/sh # # $FreeBSD$ # # If there is a global system configuration file, suck it in. # newline=" " # A single newline if [ -r /etc/defaults/periodic.conf ] then . /etc/defaults/periodic.conf source_periodic_confs fi : ${daily_scrub_zfs_default_threshold=35} case "$daily_scrub_zfs_enable" in [Yy][Ee][Ss]) echo echo 'Scrubbing of zfs pools:' if [ -z "${daily_scrub_zfs_pools}" ]; then daily_scrub_zfs_pools="$(zpool list -H -o name)" fi rc=0 for pool in ${daily_scrub_zfs_pools}; do # sanity check _status=$(zpool list "${pool}" 2> /dev/null) if [ $? -ne 0 ]; then rc=2 echo " WARNING: pool '${pool}' specified in" echo " '/etc/periodic.conf:daily_scrub_zfs_pools'" echo " does not exist" continue fi _status=${_status##*$newline} case ${_status} in *FAULTED*) rc=3 echo "Skipping faulted pool: ${pool}" continue ;; + *UNAVAIL*) + rc=4 + echo "Skipping unavailable pool: ${pool}" + continue ;; esac # determine how many days shall be between scrubs eval _pool_threshold=\${daily_scrub_zfs_$(echo "${pool}"|tr ".:-" "_")_threshold} if [ -z "${_pool_threshold}" ];then _pool_threshold=${daily_scrub_zfs_default_threshold} fi _last_scrub=$(zpool history ${pool} | \ egrep "^[0-9\.\:\-]{19} zpool scrub ${pool}\$" | tail -1 |\ cut -d ' ' -f 1) if [ -z "${_last_scrub}" ]; then # creation time of the pool if no scrub was done _last_scrub=$(zpool history ${pool} | \ sed -ne '2s/ .*$//p') fi # Now minus last scrub (both in seconds) converted to days. _scrub_diff=$(expr -e \( $(date +%s) - \ $(date -j -f %F.%T ${_last_scrub} +%s) \) / 60 / 60 / 24) if [ ${_scrub_diff} -lt ${_pool_threshold} ]; then echo " skipping scrubbing of pool '${pool}':" echo " last scrubbing is ${_scrub_diff} days ago, threshold is set to ${_pool_threshold} days" continue fi _status="$(zpool status ${pool} | grep scrub:)" case "${_status}" in *"scrub in progress"*) echo " scrubbing of pool '${pool}' already in progress, skipping:" ;; *"none requested"*) echo " starting first scrub (since reboot) of pool '${pool}':" zpool scrub ${pool} [ $rc -eq 0 ] && rc=1 ;; *) echo " starting scrub of pool '${pool}':" zpool scrub ${pool} [ $rc -eq 0 ] && rc=1 ;; esac echo " consult 'zpool status ${pool}' for the result" done ;; *) rc=0 ;; esac exit $rc Index: user/ngie/stable-10-libnv/etc/periodic/security/520.pfdenied =================================================================== --- user/ngie/stable-10-libnv/etc/periodic/security/520.pfdenied (revision 292856) +++ user/ngie/stable-10-libnv/etc/periodic/security/520.pfdenied (revision 292857) @@ -1,54 +1,54 @@ #!/bin/sh - # # Copyright (c) 2004 The FreeBSD Project # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # $FreeBSD$ # # If there is a global system configuration file, suck it in. # if [ -r /etc/defaults/periodic.conf ] then . /etc/defaults/periodic.conf source_periodic_confs fi . /etc/periodic/security/security.functions security_daily_compat_var security_status_pfdenied_enable rc=0 if check_yesno_period security_status_pfdenied_enable then TMP=`mktemp -t security` - if pfctl -sr -v 2>/dev/null | nawk '{if (/^block/) {buf=$0; getline; gsub(" +"," ",$0); print buf$0;} }' > ${TMP}; then + if pfctl -sr -v 2>/dev/null | nawk '{if (/^block/) {buf=$0; getline; gsub(" +"," ",$0); if ($5 > 0) print buf$0;} }' > ${TMP}; then check_diff new_only pf ${TMP} "${host} pf denied packets:" fi rc=$? rm -f ${TMP} fi exit $rc Index: user/ngie/stable-10-libnv/etc/services =================================================================== --- user/ngie/stable-10-libnv/etc/services (revision 292856) +++ user/ngie/stable-10-libnv/etc/services (revision 292857) @@ -1,2489 +1,2490 @@ # # Network services, Internet style # # Note that it is presently the policy of IANA to assign a single well-known # port number for both TCP and UDP; hence, most entries here have two entries # even if the protocol doesn't support UDP operations. # # The latest IANA port assignments can be gotten from # # http://www.iana.org/assignments/port-numbers # # The Well Known Ports are those from 0 through 1023. # The Registered Ports are those from 1024 through 49151 # The Dynamic and/or Private Ports are those from 49152 through 65535 # # Kerberos services are for Kerberos v4, and are unofficial. Sites running # v5 should uncomment v5 entries and comment v4 entries. # # $FreeBSD$ # From: @(#)services 5.8 (Berkeley) 5/9/91 # # WELL KNOWN PORT NUMBERS # rtmp 1/ddp #Routing Table Maintenance Protocol tcpmux 1/tcp #TCP Port Service Multiplexer tcpmux 1/udp #TCP Port Service Multiplexer nbp 2/ddp #Name Binding Protocol compressnet 2/tcp #Management Utility compressnet 2/udp #Management Utility compressnet 3/tcp #Compression Process compressnet 3/udp #Compression Process echo 4/ddp #AppleTalk Echo Protocol rje 5/tcp #Remote Job Entry rje 5/udp #Remote Job Entry zip 6/ddp #Zone Information Protocol echo 7/sctp echo 7/tcp echo 7/udp discard 9/sctp sink null discard 9/tcp sink null discard 9/udp sink null systat 11/tcp users #Active Users systat 11/udp users #Active Users daytime 13/sctp daytime 13/tcp daytime 13/udp qotd 17/tcp quote #Quote of the Day qotd 17/udp quote #Quote of the Day msp 18/tcp #Message Send Protocol msp 18/udp #Message Send Protocol chargen 19/sctp ttytst source #Character Generator chargen 19/tcp ttytst source #Character Generator chargen 19/udp ttytst source #Character Generator ftp-data 20/sctp #File Transfer [Default Data] ftp-data 20/tcp #File Transfer [Default Data] ftp-data 20/udp #File Transfer [Default Data] ftp 21/sctp #File Transfer [Control] ftp 21/tcp #File Transfer [Control] ftp 21/udp #File Transfer [Control] ssh 22/sctp #Secure Shell Login ssh 22/tcp #Secure Shell Login ssh 22/udp #Secure Shell Login telnet 23/tcp telnet 23/udp # 24/tcp any private mail system # 24/udp any private mail system smtp 25/tcp mail #Simple Mail Transfer smtp 25/udp mail #Simple Mail Transfer nsw-fe 27/tcp #NSW User System FE nsw-fe 27/udp #NSW User System FE msg-icp 29/tcp #MSG ICP msg-icp 29/udp #MSG ICP msg-auth 31/tcp #MSG Authentication msg-auth 31/udp #MSG Authentication dsp 33/tcp #Display Support Protocol dsp 33/udp #Display Support Protocol # 35/tcp any private printer server # 35/udp any private printer server time 37/tcp timserver time 37/udp timserver rap 38/tcp #Route Access Protocol rap 38/udp #Route Access Protocol rlp 39/tcp resource #Resource Location Protocol rlp 39/udp resource #Resource Location Protocol graphics 41/tcp graphics 41/udp nameserver 42/tcp name #Host Name Server nameserver 42/udp name #Host Name Server nicname 43/tcp whois nicname 43/udp whois mpm-flags 44/tcp #MPM FLAGS Protocol mpm-flags 44/udp #MPM FLAGS Protocol mpm 45/tcp #Message Processing Module [recv] mpm 45/udp #Message Processing Module [recv] mpm-snd 46/tcp #MPM [default send] mpm-snd 46/udp #MPM [default send] ni-ftp 47/tcp #NI FTP ni-ftp 47/udp #NI FTP auditd 48/tcp #Digital Audit Daemon auditd 48/udp #Digital Audit Daemon tacacs 49/tcp #Login Host Protocol (TACACS) tacacs 49/udp #Login Host Protocol (TACACS) re-mail-ck 50/tcp #Remote Mail Checking Protocol re-mail-ck 50/udp #Remote Mail Checking Protocol la-maint 51/tcp #IMP Logical Address Maintenance la-maint 51/udp #IMP Logical Address Maintenance xns-time 52/tcp #XNS Time Protocol xns-time 52/udp #XNS Time Protocol domain 53/tcp #Domain Name Server domain 53/udp #Domain Name Server xns-ch 54/tcp #XNS Clearinghouse xns-ch 54/udp #XNS Clearinghouse isi-gl 55/tcp #ISI Graphics Language isi-gl 55/udp #ISI Graphics Language xns-auth 56/tcp #XNS Authentication xns-auth 56/udp #XNS Authentication # 57/tcp any private terminal access # 57/udp any private terminal access xns-mail 58/tcp #XNS Mail xns-mail 58/udp #XNS Mail # 59/tcp any private file service # 59/udp any private file service ni-mail 61/tcp #NI MAIL ni-mail 61/udp #NI MAIL acas 62/tcp #ACA Services acas 62/udp #ACA Services whois++ 63/tcp whois++ 63/udp covia 64/tcp #Communications Integrator (CI) covia 64/udp #Communications Integrator (CI) tacacs-ds 65/tcp #TACACS-Database Service tacacs-ds 65/udp #TACACS-Database Service sql*net 66/tcp #Oracle SQL*NET sql*net 66/udp #Oracle SQL*NET bootps 67/tcp dhcps #Bootstrap Protocol Server bootps 67/udp dhcps #Bootstrap Protocol Server bootpc 68/tcp dhcpc #Bootstrap Protocol Client bootpc 68/udp dhcpc #Bootstrap Protocol Client tftp 69/tcp #Trivial File Transfer tftp 69/udp #Trivial File Transfer gopher 70/tcp gopher 70/udp netrjs-1 71/tcp #Remote Job Service netrjs-1 71/udp #Remote Job Service netrjs-2 72/tcp #Remote Job Service netrjs-2 72/udp #Remote Job Service netrjs-3 73/tcp #Remote Job Service netrjs-3 73/udp #Remote Job Service netrjs-4 74/tcp #Remote Job Service netrjs-4 74/udp #Remote Job Service # 75/tcp any private dial out service # 75/udp any private dial out service deos 76/tcp #Distributed External Object Store deos 76/udp #Distributed External Object Store # 77/tcp any private RJE service # 77/udp any private RJE service vettcp 78/tcp vettcp 78/udp finger 79/tcp finger 79/udp http 80/sctp www www-http #World Wide Web HTTP http 80/tcp www www-http #World Wide Web HTTP http 80/udp www www-http #World Wide Web HTTP hosts2-ns 81/tcp #HOSTS2 Name Server hosts2-ns 81/udp #HOSTS2 Name Server xfer 82/tcp #XFER Utility xfer 82/udp #XFER Utility mit-ml-dev 83/tcp #MIT ML Device mit-ml-dev 83/udp #MIT ML Device ctf 84/tcp #Common Trace Facility ctf 84/udp #Common Trace Facility mit-ml-dev 85/tcp #MIT ML Device mit-ml-dev 85/udp #MIT ML Device mfcobol 86/tcp #Micro Focus Cobol mfcobol 86/udp #Micro Focus Cobol # 87/tcp any private terminal link # 87/udp any private terminal link kerberos-sec 88/tcp kerberos # krb5 # Kerberos (v5) kerberos-sec 88/udp kerberos # krb5 # Kerberos (v5) su-mit-tg 89/tcp #SU/MIT Telnet Gateway su-mit-tg 89/udp #SU/MIT Telnet Gateway dnsix 90/tcp #DNSIX Securit Attribute Token Map dnsix 90/udp #DNSIX Securit Attribute Token Map mit-dov 91/tcp #MIT Dover Spooler mit-dov 91/udp #MIT Dover Spooler npp 92/tcp #Network Printing Protocol npp 92/udp #Network Printing Protocol dcp 93/tcp #Device Control Protocol dcp 93/udp #Device Control Protocol objcall 94/tcp #Tivoli Object Dispatcher objcall 94/udp #Tivoli Object Dispatcher supdup 95/tcp supdup 95/udp dixie 96/tcp #DIXIE Protocol Specification dixie 96/udp #DIXIE Protocol Specification swift-rvf 97/tcp #Swift Remote Virtural File Protocol swift-rvf 97/udp #Swift Remote Virtural File Protocol tacnews 98/tcp #TAC News, Unofficial: Red Hat linuxconf tacnews 98/udp #TAC News, Unofficial: Red Hat linuxconf metagram 99/tcp #Metagram Relay metagram 99/udp #Metagram Relay newacct 100/tcp #[unauthorized use] hostname 101/tcp hostnames #NIC Host Name Server hostname 101/udp hostnames #NIC Host Name Server iso-tsap 102/tcp tsap #ISO-TSAP Class 0 iso-tsap 102/udp tsap #ISO-TSAP Class 0 gppitnp 103/tcp #Genesis Point-to-Point Trans Net gppitnp 103/udp #Genesis Point-to-Point Trans Net acr-nema 104/tcp #ACR-NEMA Digital Imag. & Comm. 300 acr-nema 104/udp #ACR-NEMA Digital Imag. & Comm. 300 csnet-ns 105/tcp cso-ns cso #Mailbox Name Nameserver csnet-ns 105/udp cso-ns cso #Mailbox Name Nameserver pop3pw 106/tcp 3com-tsmux #Eudora compatible PW changer 3com-tsmux 106/udp rtelnet 107/tcp #Remote Telnet Service rtelnet 107/udp #Remote Telnet Service snagas 108/tcp #SNA Gateway Access Server snagas 108/udp #SNA Gateway Access Server pop2 109/tcp postoffice #Post Office Protocol - Version 2 pop2 109/udp postoffice #Post Office Protocol - Version 2 pop3 110/tcp #Post Office Protocol - Version 3 pop3 110/udp #Post Office Protocol - Version 3 sunrpc 111/tcp rpcbind #SUN Remote Procedure Call sunrpc 111/udp rpcbind #SUN Remote Procedure Call mcidas 112/tcp #McIDAS Data Transmission Protocol mcidas 112/udp #McIDAS Data Transmission Protocol auth 113/tcp ident tap #Authentication Service auth 113/udp ident tap #Authentication Service sftp 115/tcp #Simple File Transfer Protocol sftp 115/udp #Simple File Transfer Protocol ansanotify 116/tcp #ANSA REX Notify ansanotify 116/udp #ANSA REX Notify uucp-path 117/tcp #UUCP Path Service uucp-path 117/udp #UUCP Path Service sqlserv 118/tcp #SQL Services sqlserv 118/udp #SQL Services nntp 119/tcp usenet #Network News Transfer Protocol nntp 119/udp usenet #Network News Transfer Protocol cfdptkt 120/tcp cfdptkt 120/udp erpc 121/tcp #Encore Expedited Remote Pro.Call erpc 121/udp #Encore Expedited Remote Pro.Call smakynet 122/tcp smakynet 122/udp ntp 123/tcp #Network Time Protocol ntp 123/udp #Network Time Protocol ansatrader 124/tcp #ANSA REX Trader ansatrader 124/udp #ANSA REX Trader locus-map 125/tcp #Locus PC-Interface Net Map Ser locus-map 125/udp #Locus PC-Interface Net Map Ser unitary 126/tcp #Unisys Unitary Login unitary 126/udp #Unisys Unitary Login locus-con 127/tcp #Locus PC-Interface Conn Server locus-con 127/udp #Locus PC-Interface Conn Server gss-xlicen 128/tcp #GSS X License Verification gss-xlicen 128/udp #GSS X License Verification pwdgen 129/tcp #Password Generator Protocol pwdgen 129/udp #Password Generator Protocol cisco-fna 130/tcp #cisco FNATIVE cisco-fna 130/udp #cisco FNATIVE cisco-tna 131/tcp #cisco TNATIVE cisco-tna 131/udp #cisco TNATIVE cisco-sys 132/tcp #cisco SYSMAINT cisco-sys 132/udp #cisco SYSMAINT statsrv 133/tcp #Statistics Service statsrv 133/udp #Statistics Service ingres-net 134/tcp #INGRES-NET Service ingres-net 134/udp #INGRES-NET Service loc-srv 135/tcp epmap #Location Service loc-srv 135/udp epmap #Location Service profile 136/tcp #PROFILE Naming System profile 136/udp #PROFILE Naming System netbios-ns 137/tcp #NETBIOS Name Service netbios-ns 137/udp #NETBIOS Name Service netbios-dgm 138/tcp #NETBIOS Datagram Service netbios-dgm 138/udp #NETBIOS Datagram Service netbios-ssn 139/tcp #NETBIOS Session Service netbios-ssn 139/udp #NETBIOS Session Service emfis-data 140/tcp #EMFIS Data Service emfis-data 140/udp #EMFIS Data Service emfis-cntl 141/tcp #EMFIS Control Service emfis-cntl 141/udp #EMFIS Control Service bl-idm 142/tcp #Britton-Lee IDM bl-idm 142/udp #Britton-Lee IDM imap 143/tcp imap2 imap4 #Interim Mail Access Protocol v2 imap 143/udp imap2 imap4 #Interim Mail Access Protocol v2 NeWS 144/tcp # Window System NeWS 144/udp # Window System #PROBLEMS!============================================================== #uma 144/tcp #Universal Management Architecture #uma 144/udp #Universal Management Architecture #PROBLEMS!============================================================== uaac 145/tcp #UAAC Protocol uaac 145/udp #UAAC Protocol iso-tp0 146/tcp iso-tp0 146/udp iso-ip 147/tcp iso-ip 147/udp cronus 148/tcp jargon #CRONUS-SUPPORT cronus 148/udp jargon #CRONUS-SUPPORT aed-512 149/tcp #AED 512 Emulation Service aed-512 149/udp #AED 512 Emulation Service sql-net 150/tcp sql-net 150/udp hems 151/tcp hems 151/udp bftp 152/tcp #Background File Transfer Program bftp 152/udp #Background File Transfer Program sgmp 153/tcp sgmp 153/udp netsc-prod 154/tcp netsc-prod 154/udp netsc-dev 155/tcp netsc-dev 155/udp sqlsrv 156/tcp #SQL Service sqlsrv 156/udp #SQL Service knet-cmp 157/tcp #KNET/VM Command/Message Protocol knet-cmp 157/udp #KNET/VM Command/Message Protocol pcmail-srv 158/tcp #PCMail Server pcmail-srv 158/udp #PCMail Server nss-routing 159/tcp nss-routing 159/udp sgmp-traps 160/tcp sgmp-traps 160/udp snmp 161/tcp snmp 161/udp snmptrap 162/tcp snmp-trap snmptrap 162/udp snmp-trap cmip-man 163/tcp #CMIP/TCP Manager cmip-man 163/udp #CMIP/TCP Manager cmip-agent 164/tcp #CMIP/TCP Agent smip-agent 164/udp #CMIP/TCP Agent xns-courier 165/tcp #Xerox xns-courier 165/udp #Xerox s-net 166/tcp #Sirius Systems s-net 166/udp #Sirius Systems namp 167/tcp namp 167/udp rsvd 168/tcp rsvd 168/udp send 169/tcp send 169/udp print-srv 170/tcp #Network PostScript print-srv 170/udp #Network PostScript multiplex 171/tcp #Network Innovations Multiplex multiplex 171/udp #Network Innovations Multiplex cl/1 172/tcp #Network Innovations CL/1 cl/1 172/udp #Network Innovations CL/1 xyplex-mux 173/tcp xyplex-mux 173/udp mailq 174/tcp mailq 174/udp vmnet 175/tcp vmnet 175/udp genrad-mux 176/tcp genrad-mux 176/udp xdmcp 177/tcp #X Display Manager Control Protocol xdmcp 177/udp #X Display Manager Control Protocol NextStep 178/tcp nextstep NeXTStep #NextStep Window Server NextStep 178/udp nextstep NeXTStep #NextStep Window Server bgp 179/sctp #Border Gateway Protocol bgp 179/tcp #Border Gateway Protocol bgp 179/udp #Border Gateway Protocol ris 180/tcp #Intergraph ris 180/udp #Intergraph unify 181/tcp unify 181/udp audit 182/tcp #Unisys Audit SITP audit 182/udp #Unisys Audit SITP ocbinder 183/tcp ocbinder 183/udp ocserver 184/tcp ocserver 184/udp remote-kis 185/tcp remote-kis 185/udp kis 186/tcp #KIS Protocol kis 186/udp #KIS Protocol aci 187/tcp #Application Communication Interface aci 187/udp #Application Communication Interface mumps 188/tcp #Plus Five's MUMPS mumps 188/udp #Plus Five's MUMPS qft 189/tcp #Queued File Transport qft 189/udp #Queued File Transport gacp 190/tcp #Gateway Access Control Protocol gacp 190/udp cacp #Gateway Access Control Protocol prospero 191/tcp #Prospero Directory Service prospero 191/udp #Prospero Directory Service osu-nms 192/tcp #OSU Network Monitoring System osu-nms 192/udp #OSU Network Monitoring System srmp 193/tcp #Spider Remote Monitoring Protocol srmp 193/udp #Spider Remote Monitoring Protocol irc 194/tcp #Internet Relay Chat Protocol irc 194/udp #Internet Relay Chat Protocol dn6-nlm-aud 195/tcp #DNSIX Network Level Module Audit dn6-nlm-aud 195/udp #DNSIX Network Level Module Audit dn6-smm-red 196/tcp #DNSIX Session Mgt Module Audit Redir dn6-smm-red 196/udp #DNSIX Session Mgt Module Audit Redir dls 197/tcp #Directory Location Service dls 197/udp #Directory Location Service dls-mon 198/tcp #Directory Location Service Monitor dls-mon 198/udp #Directory Location Service Monitor smux 199/tcp smux 199/udp src 200/tcp #IBM System Resource Controller src 200/udp #IBM System Resource Controller at-rtmp 201/tcp #AppleTalk Routing Maintenance at-rtmp 201/udp #AppleTalk Routing Maintenance at-nbp 202/tcp #AppleTalk Name Binding at-nbp 202/udp #AppleTalk Name Binding at-3 203/tcp #AppleTalk Unused at-3 203/udp #AppleTalk Unused at-echo 204/tcp #AppleTalk Echo at-echo 204/udp #AppleTalk Echo at-5 205/tcp #AppleTalk Unused at-5 205/udp #AppleTalk Unused at-zis 206/tcp #AppleTalk Zone Information at-zis 206/udp #AppleTalk Zone Information at-7 207/tcp #AppleTalk Unused at-7 207/udp #AppleTalk Unused at-8 208/tcp #AppleTalk Unused at-8 208/udp #AppleTalk Unused qmtp 209/tcp #The Quick Mail Transfer Protocol qmtp 209/udp #The Quick Mail Transfer Protocol #PROBLEMS!============================================================== #tam 209/tcp #Trivial Authenticated Mail Protocol #tam 209/udp #Trivial Authenticated Mail Protocol #PROBLEMS!============================================================== z39.50 210/tcp wais #ANSI Z39.50 z39.50 210/udp wais #ANSI Z39.50 914c/g 211/tcp #Texas Instruments 914C/G Terminal 914c/g 211/udp #Texas Instruments 914C/G Terminal anet 212/tcp #ATEXSSTR anet 212/udp #ATEXSSTR ipx 213/tcp ipx 213/udp vmpwscs 214/tcp vmpwscs 214/udp softpc 215/tcp #Insignia Solutions softpc 215/udp #Insignia Solutions CAIlic 216/tcp atls #Computer Associates Int'l License Server CAIlic 216/udp atls #Computer Associates Int'l License Server dbase 217/tcp #dBASE Unix dbase 217/udp #dBASE Unix mpp 218/tcp #Netix Message Posting Protocol mpp 218/udp #Netix Message Posting Protocol uarps 219/tcp #Unisys ARPs uarps 219/udp #Unisys ARPs imap3 220/tcp #Interactive Mail Access Protocol v3 imap3 220/udp #Interactive Mail Access Protocol v3 fln-spx 221/tcp #Berkeley rlogind with SPX auth fln-spx 221/udp #Berkeley rlogind with SPX auth rsh-spx 222/tcp #Berkeley rshd with SPX auth rsh-spx 222/udp #Berkeley rshd with SPX auth cdc 223/tcp #Certificate Distribution Center cdc 223/udp #Certificate Distribution Center masqdialer 224/tcp masqdialer 224/udp direct 242/tcp direct 242/udp sur-meas 243/tcp #Survey Measurement sur-meas 243/udp #Survey Measurement dayna 244/tcp dayna 244/udp link 245/tcp link 245/udp dsp3270 246/tcp #Display Systems Protocol dsp3270 246/udp #Display Systems Protocol subntbcst_tftp 247/tcp #subntbcst_tftp subntbcst_tftp 247/udp #subntbcst_tftp bhfhs 248/tcp bhfhs 248/udp # 249-255 reserved rap 256/tcp rap 256/udp set 257/tcp #secure electronic transaction set 257/udp #secure electronic transaction esro-gen 259/tcp #efficient short remote operations esro-gen 259/udp #efficient short remote operations openport 260/tcp openport 260/udp nsiiops 261/tcp #iiop name service over tls/ssl nsiiops 261/udp #iiop name service over tls/ssl arcisdms 262/tcp arcisdms 262/udp hdap 263/tcp hdap 263/udp bgmp 264/tcp bgmp 264/udp x-bone-ctl 265/tcp #X-Bone CTL x-bone-ctl 265/udp #X-Bone CTL sst 266/tcp #SCSI on ST sst 266/udp #SCSI on ST td-service 267/tcp #Tobit David Service Layer td-service 267/udp #Tobit David Service Layer td-replica 268/tcp #Tobit David Replica td-replica 268/udp #Tobit David Replica # 269-279 unassigned http-mgmt 280/tcp http-mgmt 280/udp personal-link 281/tcp personal-link 281/udp cableport-ax 282/tcp #cable port a/x cableport-ax 282/udp #cable port a/x rescap 283/tcp rescap 283/udp corerjd 284/tcp corerjd 284/udp # 285 unassigned fxp 286/tcp fxp 286/udp k-block 287/tcp k-block 287/udp # 288-307 unassigned novastorbakcup 308/tcp #novastor backup novastorbakcup 308/udp #novastor backup entrusttime 309/tcp entrusttime 309/udp bhmds 310/tcp bhmds 310/udp asip-webadmin 311/tcp #appleshare ip webadmin asip-webadmin 311/udp #appleshare ip webadmin vslmp 312/tcp vslmp 312/udp magenta-logic 313/tcp magenta-logic 313/udp opalis-robot 314/tcp opalis-robot 314/udp dpsi 315/tcp dpsi 315/udp decauth 316/tcp decauth 316/udp zannet 317/tcp zannet 317/udp pkix-timestamp 318/tcp #PKIX TimeStamp pkix-timestamp 318/udp #PKIX TimeStamp ptp-event 319/tcp #PTP Event ptp-event 319/udp #PTP Event ptp-general 320/tcp #PTP General ptp-general 320/udp #PTP General pip 321/tcp pip 321/udp rtsps 322/tcp rtsps 322/udp # 323-332 #unassigned texar 333/tcp #Texar Security Port texar 333/udp #Texar Security Port # 334-343 #unassigned pdap 344/tcp #Prospero Data Access Protocol pdap 344/udp #Prospero Data Access Protocol pawserv 345/tcp #Perf Analysis Workbench pawserv 345/udp #Perf Analysis Workbench zserv 346/tcp #Zebra server zserv 346/udp #Zebra server fatserv 347/tcp #Fatmen Server fatserv 347/udp #Fatmen Server csi-sgwp 348/tcp #Cabletron Management Protocol csi-sgwp 348/udp #Cabletron Management Protocol mftp 349/tcp mftp 349/udp matip-type-a 350/tcp #MATIP Type A matip-type-a 350/udp matip-type-b 351/tcp #MATIP Type B matip-type-b 351/udp bhoetty 351/tcp #unassigned but widespread use bhoetty 351/udp #unassigned but widespread use dtag-ste-sb 352/tcp #DTAG dtag-ste-sb 352/udp #DTAG bhoedap4 352/tcp #unassigned but widespread use bhoedap4 352/udp #unassigned but widespread use ndsauth 353/tcp ndsauth 353/udp bh611 354/tcp bh611 354/udp datex-asn 355/tcp datex-asn 355/udp cloanto-net-1 356/tcp #Cloanto Net 1 cloanto-net-1 356/udp bhevent 357/tcp bhevent 357/udp shrinkwrap 358/tcp shrinkwrap 358/udp tenebris_nts 359/tcp #Tenebris Network Trace Service tenebris_nts 359/udp #Tenebris Network Trace Service scoi2odialog 360/tcp scoi2odialog 360/udp semantix 361/tcp semantix 361/udp srssend 362/tcp #SRS Send srssend 362/udp #SRS Send rsvp_tunnel 363/tcp rsvp_tunnel 363/udp aurora-cmgr 364/tcp aurora-cmgr 364/udp dtk 365/tcp #Deception Tool Kit - Fred Cohen dtk 365/udp #Deception Tool Kit - Fred Cohen odmr 366/tcp odmr 366/udp mortgageware 367/tcp mortgageware 367/udp qbikgdp 368/tcp #QbikGDP qbikgdp 368/udp rpc2portmap 369/tcp rpc2portmap 369/udp codaauth2 370/tcp codaauth2 370/udp clearcase 371/tcp clearcase 371/udp ulistserv 372/tcp ulistproc #Unix Listserv ulistserv 372/udp ulistproc #Unix Listserv legent-1 373/tcp #Legent Corporation (now Computer Associates Intl.) legent-1 373/udp #Legent Corporation (now Computer Associates Intl.) legent-2 374/tcp #Legent Corporation (now Computer Associates Intl.) legent-2 374/udp #Legent Corporation (now Computer Associates Intl.) hassle 375/tcp hassle 375/udp nip 376/tcp #Amiga Envoy Network Inquiry Proto nip 376/udp #Amiga Envoy Network Inquiry Proto tnETOS 377/tcp #NEC Corporation tnETOS 377/udp #NEC Corporation dsETOS 378/tcp #NEC Corporation dsETOS 378/udp #NEC Corporation is99c 379/tcp #TIA/EIA/IS-99 modem client is99c 379/udp #TIA/EIA/IS-99 modem client is99s 380/tcp #TIA/EIA/IS-99 modem server is99s 380/udp #TIA/EIA/IS-99 modem server hp-collector 381/tcp #hp performance data collector hp-collector 381/udp #hp performance data collector hp-managed-node 382/tcp #hp performance data managed node hp-managed-node 382/udp #hp performance data managed node hp-alarm-mgr 383/tcp #hp performance data alarm manager hp-alarm-mgr 383/udp #hp performance data alarm manager arns 384/tcp #A Remote Network Server System arns 384/udp #A Remote Network Server System ibm-app 385/tcp #IBM Application ibm-app 385/udp #IBM Application asa 386/tcp #ASA Message Router Object Def. asa 386/udp #ASA Message Router Object Def. aurp 387/tcp #Appletalk Update-Based Routing Pro. aurp 387/udp #Appletalk Update-Based Routing Pro. unidata-ldm 388/tcp #Unidata LDM Version 4 unidata-ldm 388/udp #Unidata LDM Version 4 ldap 389/tcp #Lightweight Directory Access Protocol ldap 389/udp #Lightweight Directory Access Protocol uis 390/tcp uis 390/udp synotics-relay 391/tcp #SynOptics SNMP Relay Port synotics-relay 391/udp #SynOptics SNMP Relay Port synotics-broker 392/tcp #SynOptics Port Broker Port synotics-broker 392/udp #SynOptics Port Broker Port dis 393/tcp #Data Interpretation System dis 393/udp #Data Interpretation System embl-ndt 394/tcp #EMBL Nucleic Data Transfer embl-ndt 394/udp #EMBL Nucleic Data Transfer netcp 395/tcp #NETscout Control Protocol netcp 395/udp #NETscout Control Protocol netware-ip 396/tcp #Novell Netware over IP netware-ip 396/udp #Novell Netware over IP mptn 397/tcp #Multi Protocol Trans. Net. mptn 397/udp #Multi Protocol Trans. Net. kryptolan 398/tcp kryptolan 398/udp iso-tsap-c2 399/tcp #ISO-TSAP Class 2 iso-tsap-c2 399/udp #ISO-TSAP Class 2 work-sol 400/tcp #Workstation Solutions work-sol 400/udp #Workstation Solutions ups 401/tcp #Uninterruptible Power Supply ups 401/udp #Uninterruptible Power Supply genie 402/tcp #Genie Protocol genie 402/udp #Genie Protocol decap 403/tcp decap 403/udp nced 404/tcp nced 404/udp ncld 405/tcp ncld 405/udp imsp 406/tcp #Interactive Mail Support Protocol imsp 406/udp #Interactive Mail Support Protocol timbuktu 407/tcp timbuktu 407/udp prm-sm 408/tcp #Prospero Resource Manager Sys. Man. prm-sm 408/udp #Prospero Resource Manager Sys. Man. prm-nm 409/tcp #Prospero Resource Manager Node Man. prm-nm 409/udp #Prospero Resource Manager Node Man. decladebug 410/tcp #DECLadebug Remote Debug Protocol decladebug 410/udp #DECLadebug Remote Debug Protocol rmt 411/tcp #Remote MT Protocol rmt 411/udp #Remote MT Protocol synoptics-trap 412/tcp #Trap Convention Port synoptics-trap 412/udp #Trap Convention Port smsp 413/tcp smsp 413/udp infoseek 414/tcp infoseek 414/udp bnet 415/tcp bnet 415/udp silverplatter 416/tcp silverplatter 416/udp onmux 417/tcp onmux 417/udp hyper-g 418/tcp hyper-g 418/udp ariel1 419/tcp ariel1 419/udp smpte 420/tcp smpte 420/udp ariel2 421/tcp ariel2 421/udp ariel3 422/tcp ariel3 422/udp opc-job-start 423/tcp #IBM Operations Planning and Control Start opc-job-start 423/udp #IBM Operations Planning and Control Start opc-job-track 424/tcp #IBM Operations Planning and Control Track opc-job-track 424/udp #IBM Operations Planning and Control Track icad-el 425/tcp icad-el 425/udp smartsdp 426/tcp smartsdp 426/udp svrloc 427/tcp #Server Location svrloc 427/udp #Server Location ocs_cmu 428/tcp ocs_cmu 428/udp ocs_amu 429/tcp ocs_amu 429/udp utmpsd 430/tcp utmpsd 430/udp utmpcd 431/tcp utmpcd 431/udp iasd 432/tcp iasd 432/udp nnsp 433/tcp nnsp 433/udp mobileip-agent 434/tcp mobileip-agent 434/udp mobilip-mn 435/tcp mobilip-mn 435/udp dna-cml 436/tcp dna-cml 436/udp comscm 437/tcp comscm 437/udp dsfgw 438/tcp dsfgw 438/udp dasp 439/tcp dasp 439/udp sgcp 440/tcp sgcp 440/udp decvms-sysmgt 441/tcp decvms-sysmgt 441/udp cvc_hostd 442/tcp cvc_hostd 442/udp https 443/sctp https 443/tcp https 443/udp snpp 444/tcp #Simple Network Paging Protocol snpp 444/udp #Simple Network Paging Protocol # [RFC1568] microsoft-ds 445/tcp microsoft-ds 445/udp ddm-rdb 446/tcp ddm-rdb 446/udp ddm-dfm 447/tcp ddm-dfm 447/udp ddm-ssl 448/tcp ddm-byte ddm-ssl 448/udp ddm-byte as-servermap 449/tcp #AS Server Mapper as-servermap 449/udp #AS Server Mapper tserver 450/tcp tserver 450/udp sfs-smp-net 451/tcp #Cray Network Semaphore server sfs-smp-net 451/udp #Cray Network Semaphore server sfs-config 452/tcp #Cray SFS config server sfs-config 452/udp #Cray SFS config server creativeserver 453/tcp #CreativeServer creativeserver 453/udp #CreativeServer contentserver 454/tcp #ContentServer contentserver 454/udp #ContentServer creativepartnr 455/tcp #CreativePartnr creativepartnr 455/udp #CreativePartnr macon-tcp 456/tcp macon-udp 456/udp scohelp 457/tcp scohelp 457/udp appleqtc 458/tcp #apple quick time appleqtc 458/udp #apple quick time ampr-rcmd 459/tcp ampr-rcmd 459/udp skronk 460/tcp skronk 460/udp datasurfsrv 461/tcp datasurfsrv 461/udp datasurfsrvsec 462/tcp datasurfsrvsec 462/udp alpes 463/tcp alpes 463/udp # kpasswd5 464/tcp # Kerberos (v5) kpasswd5 464/udp # Kerberos (v5) #PROBLEMS!============================================================== # IANA has officially assigned these two ports as ``kpasswd'' #kpasswd 464/tcp # Kerberos (v5) #kpasswd 464/udp # Kerberos (v5) #PROBLEMS!============================================================== smtps 465/tcp #smtp protocol over TLS/SSL (was ssmtp) smtps 465/udp #smtp protocol over TLS/SSL (was ssmtp) digital-vrc 466/tcp digital-vrc 466/udp mylex-mapd 467/tcp mylex-mapd 467/udp photuris 468/tcp photuris 468/udp rcp 469/tcp #Radio Control Protocol rcp 469/udp #Radio Control Protocol scx-proxy 470/tcp scx-proxy 470/udp mondex 471/tcp mondex 471/udp ljk-login 472/tcp ljk-login 472/udp hybrid-pop 473/tcp hybrid-pop 473/udp tn-tl-w1 474/tcp tn-tl-w2 474/udp tcpnethaspsrv 475/tcp tcpnethaspsrv 475/udp tn-tl-fd1 476/tcp tn-tl-fd1 476/udp ss7ns 477/tcp ss7ns 477/udp spsc 478/tcp spsc 478/udp iafserver 479/tcp iafserver 479/udp iafdbase 480/tcp iafdbase 480/udp ph 481/tcp ph 481/udp bgs-nsi 482/tcp bgs-nsi 482/udp ulpnet 483/tcp ulpnet 483/udp integra-sme 484/tcp #Integra Software Management Environment integra-sme 484/udp #Integra Software Management Environment powerburst 485/tcp #Air Soft Power Burst powerburst 485/udp #Air Soft Power Burst avian 486/tcp avian 486/udp saft 487/tcp #saft Simple Asynchronous File Transfer saft 487/udp #saft Simple Asynchronous File Transfer gss-http 488/tcp gss-http 488/udp nest-protocol 489/tcp nest-protocol 489/udp micom-pfs 490/tcp micom-pfs 490/udp go-login 491/tcp go-login 491/udp ticf-1 492/tcp #Transport Independent Convergence for FNA ticf-1 492/udp #Transport Independent Convergence for FNA ticf-2 493/tcp #Transport Independent Convergence for FNA ticf-2 493/udp #Transport Independent Convergence for FNA pov-ray 494/tcp pov-ray 494/udp intecourier 495/tcp intecourier 495/udp pim-rp-disc 496/tcp pim-rp-disc 496/udp dantz 497/tcp dantz 497/udp siam 498/tcp siam 498/udp iso-ill 499/tcp #ISO ILL Protocol iso-ill 499/udp #ISO ILL Protocol isakmp 500/tcp isakmp 500/udp stmf 501/tcp stmf 501/udp asa-appl-proto 502/tcp asa-appl-proto 502/udp intrinsa 503/tcp intrinsa 503/udp citadel 504/tcp citadel 504/udp mailbox-lm 505/tcp mailbox-lm 505/udp ohimsrv 506/tcp ohimsrv 506/udp crs 507/tcp crs 507/udp xvttp 508/tcp xvttp 508/udp snare 509/tcp snare 509/udp fcp 510/tcp #FirstClass Protocol fcp 510/udp #FirstClass Protocol passgo 511/tcp passgo 511/udp # # Berkeley-specific services # exec 512/tcp #remote process execution; # authentication performed using # passwords and UNIX login names biff 512/udp comsat #used by mail system to notify users # of new mail received; currently # receives messages only from # processes on the same machine login 513/tcp #remote login a la telnet; # automatic authentication performed # based on priviledged port numbers # and distributed data bases which # identify "authentication domains" who 513/udp whod #maintains data bases showing who's # logged in to machines on a local # net and the load average of the # machine shell 514/tcp cmd #like exec, but automatic # authentication is performed as for # login server syslog 514/udp printer 515/tcp spooler printer 515/udp spooler videotex 516/tcp videotex 516/udp talk 517/tcp #like tenex link, but across # machine - unfortunately, doesn't # use link protocol (this is actually # just a rendezvous port from which a # tcp connection is established) talk 517/udp #like tenex link, but across # machine - unfortunately, doesn't # use link protocol (this is actually # just a rendezvous port from which a # tcp connection is established) ntalk 518/tcp ntalk 518/udp utime 519/tcp unixtime utime 519/udp unixtime efs 520/tcp #extended file name server router 520/udp route routed #local routing process (on site); # uses variant of Xerox NS routing # information protocol ripng 521/tcp ripng 521/udp ulp 522/tcp ulp 522/udp ibm-db2 523/tcp ibm-db2 523/udp ncp 524/tcp ncp 524/udp timed 525/tcp timeserver timed 525/udp timeserver tempo 526/tcp newdate tempo 526/udp newdate stx 527/tcp #Stock IXChange stx 527/udp #Stock IXChange custix 528/tcp #Customer IXChange custix 528/udp #Customer IXChange irc-serv 529/tcp irc-serv 529/udp courier 530/tcp rpc courier 530/udp rpc conference 531/tcp chat conference 531/udp chat netnews 532/tcp readnews netnews 532/udp readnews netwall 533/tcp #for emergency broadcasts netwall 533/udp #for emergency broadcasts mm-admin 534/tcp #MegaMedia Admin mm-admin 534/udp #MegaMedia Admin iiop 535/tcp iiop 535/udp opalis-rdv 536/tcp opalis-rdv 536/udp nmsp 537/tcp #Networked Media Streaming Protocol nmsp 537/udp #Networked Media Streaming Protocol gdomap 538/tcp gdomap 538/udp apertus-ldp 539/tcp #Apertus Technologies Load Determination apertus-ldp 539/udp #Apertus Technologies Load Determination uucp 540/tcp uucpd uucp 540/udp uucpd uucp-rlogin 541/tcp uucp-rlogin 541/udp commerce 542/tcp commerce 542/udp klogin 543/tcp # Kerberos (v4/v5) klogin 543/udp # Kerberos (v4/v5) kshell 544/tcp krcmd # Kerberos (v4/v5) kshell 544/udp krcmd # Kerberos (v4/v5) appleqtcsrvr 545/tcp appleqtcsrvr 545/udp dhcpv6-client 546/tcp #DHCPv6 Client dhcpv6-client 546/udp #DHCPv6 Client dhcpv6-server 547/tcp #DHCPv6 Server dhcpv6-server 547/udp #DHCPv6 Server afpovertcp 548/tcp #AFP over TCP afpovertcp 548/udp #AFP over TCP idfp 549/tcp idfp 549/udp new-rwho 550/tcp new-who new-rwho 550/udp new-who cybercash 551/tcp cybercash 551/udp deviceshare 552/tcp deviceshare 552/udp pirp 553/tcp pirp 553/udp rtsp 554/tcp #Real Time Stream Control Protocol rtsp 554/udp #Real Time Stream Control Protocol dsf 555/tcp dsf 555/udp remotefs 556/tcp rfs rfs_server # Brunhoff remote filesystem remotefs 556/udp rfs rfs_server # Brunhoff remote filesystem openvms-sysipc 557/tcp openvms-sysipc 557/udp sdnskmp 558/tcp sdnskmp 558/udp teedtap 559/tcp teedtap 559/udp rmonitor 560/tcp rmonitord rmonitor 560/udp rmonitord monitor 561/tcp monitor 561/udp chshell 562/tcp chcmd chshell 562/udp chcmd nntps 563/tcp snntp #nntp protocol over TLS/SSL nntps 563/udp snntp #nntp protocol over TLS/SSL 9pfs 564/tcp #plan 9 file service 9pfs 564/udp #plan 9 file service whoami 565/tcp whoami 565/udp streettalk 566/tcp -streettalk 566/udp +streettalk 566/udp banyan-rpc 567/tcp banyan-rpc 567/udp ms-shuttle 568/tcp #Microsoft shuttle ms-shuttle 568/udp #Microsoft shuttle ms-rome 569/tcp #Microsoft rome ms-rome 569/udp #Microsoft rome meter 570/tcp #demon meter 570/udp #demon umeter 571/tcp #udemon umeter 571/udp #udemon sonar 572/tcp sonar 572/udp banyan-vip 573/tcp banyan-vip 573/udp ftp-agent 574/tcp #FTP Software Agent System ftp-agent 574/udp #FTP Software Agent System vemmi 575/tcp vemmi 575/udp ipcd 576/tcp ipcd 576/udp vnas 577/tcp vnas 577/udp ipdd 578/tcp ipdd 578/udp decbsrv 579/tcp decbsrv 579/udp sntp-heartbeat 580/tcp sntp-heartbeat 580/udp bdp 581/tcp #Bundle Discovery Protocol bdp 581/udp #Bundle Discovery Protocol scc-security 582/tcp scc-security 582/udp philips-vc 583/tcp #Philips Video-Conferencing philips-vc 583/udp #Philips Video-Conferencing keyserver 584/tcp keyserver 584/udp #imap4-ssl@585 never should have been allocated. See PR 46294. #imap4-ssl 585/tcp #IMAP4+SSL (use of 585 is not recommended, #imap4-ssl 585/udp # use 993 instead) password-chg 586/tcp password-chg 586/udp submission 587/tcp submission 587/udp cal 588/tcp cal 588/udp eyelink 589/tcp eyelink 589/udp tns-cml 590/tcp tns-cml 590/udp http-alt 591/tcp #FileMaker, Inc. - HTTP Alternate (see Port 80) http-alt 591/udp #FileMaker, Inc. - HTTP Alternate (see Port 80) eudora-set 592/tcp eudora-set 592/udp http-rpc-epmap 593/tcp #HTTP RPC Ep Map http-rpc-epmap 593/udp #HTTP RPC Ep Map tpip 594/tcp tpip 594/udp cab-protocol 595/tcp cab-protocol 595/udp smsd 596/tcp smsd 596/udp ptcnameservice 597/tcp #PTC Name Service ptcnameservice 597/udp #PTC Name Service sco-websrvrmg3 598/tcp #SCO Web Server Manager 3 sco-websrvrmg3 598/udp #SCO Web Server Manager 3 acp 599/tcp #Aeolon Core Protocol acp 599/udp #Aeolon Core Protocol ipcserver 600/tcp #Sun IPC server ipcserver 600/udp #Sun IPC server -syslog-conn 601/tcp #Reliable Syslog Service -syslog-conn 601/udp #Reliable Syslog Service -xmlrpc-beep 602/tcp #XML-RPC over BEEP -xmlrpc-beep 602/udp #XML-RPC over BEEP -idxp 603/tcp -idxp 603/udp -tunnel 604/tcp -tunnel 604/udp -soap-beep 605/tcp #SOAP over BEEP -soap-beep 605/udp #SOAP over BEEP +syslog-conn 601/tcp #Reliable Syslog Service +syslog-conn 601/udp #Reliable Syslog Service +xmlrpc-beep 602/tcp #XML-RPC over BEEP +xmlrpc-beep 602/udp #XML-RPC over BEEP +idxp 603/tcp +idxp 603/udp +tunnel 604/tcp +tunnel 604/udp +soap-beep 605/tcp #SOAP over BEEP +soap-beep 605/udp #SOAP over BEEP urm 606/tcp #Cray Unified Resource Manager urm 606/udp #Cray Unified Resource Manager nqs 607/tcp nqs 607/udp sift-uft 608/tcp #Sender-Initiated/Unsolicited File Transfer sift-uft 608/udp #Sender-Initiated/Unsolicited File Transfer npmp-trap 609/tcp npmp-trap 609/udp npmp-local 610/tcp npmp-local 610/udp npmp-gui 611/tcp npmp-gui 611/udp hmmp-ind 612/tcp #HMMP Indication hmmp-ind 612/udp #HMMP Indication hmmp-op 613/tcp #HMMP Operation hmmp-op 613/udp #HMMP Operation sshell 614/tcp #SSLshell sshell 614/udp sco-inetmgr 615/tcp #Internet Configuration Manager sco-inetmgr 615/udp #Internet Configuration Manager sco-sysmgr 616/tcp #SCO System Administration Server sco-sysmgr 616/udp #SCO System Administration Server sco-dtmgr 617/tcp #SCO Desktop Administration Server sco-dtmgr 617/udp #SCO Desktop Administration Server dei-icda 618/tcp dei-icda 618/udp compaq-evm 619/tcp #Compaq EVM compaq-evm 619/udp #Compaq EVM -sco-websrvrmgr 620/tcp #SCO WebServer Manager -sco-websrvrmgr 620/udp #SCO WebServer Manager +sco-websrvrmgr 620/tcp #SCO WebServer Manager +sco-websrvrmgr 620/udp #SCO WebServer Manager escp-ip 621/tcp #ESCP escp-ip 621/udp #ESCP collaborator 622/tcp collaborator 622/udp -asf-rmcp 623/tcp #ASF Remote Management and Control Protocol -asf-rmcp 623/udp #ASF Remote Management and Control Protocol +asf-rmcp 623/tcp #ASF Remote Management and Control Protocol +asf-rmcp 623/udp #ASF Remote Management and Control Protocol cryptoadmin 624/tcp #Crypto Admin cryptoadmin 624/udp #Crypto Admin dec_dlm 625/tcp #DEC DLM dec_dlm 625/udp #DEC DLM asia 626/tcp asia 626/udp passgo-tivoli 627/tcp #PassGo Tivoli passgo-tivoli 627/udp #PassGo Tivoli qmqp 628/tcp qmqp 628/udp 3com-amp3 629/tcp #3Com AMP3 3com-amp3 629/udp #3Com AMP3 rda 630/tcp rda 630/udp ipp 631/tcp #IPP (Internet Printing Protocol) ipp 631/udp #IPP (Internet Printing Protocol) bmpp 632/tcp bmpp 632/udp servstat 633/tcp #Service Status update (Sterling Software) servstat 633/udp #Service Status update (Sterling Software) ginad 634/tcp ginad 634/udp -rlzdbase 635/tcp #RLZ DBase -rlzdbase 635/udp #RLZ DBase +rlzdbase 635/tcp #RLZ DBase +rlzdbase 635/udp #RLZ DBase ldaps 636/tcp sldap #ldap protocol over TLS/SSL ldaps 636/udp sldap -lanserver 637/tcp -lanserver 637/udp +lanserver 637/tcp +lanserver 637/udp mcns-sec 638/tcp mcns-sec 638/udp msdp 639/tcp msdp 639/udp entrust-sps 640/tcp entrust-sps 640/udp repcmd 641/tcp repcmd 641/udp esro-emsdp 642/tcp #ESRO-EMSDP V1.3 esro-emsdp 642/udp #ESRO-EMSDP V1.3 sanity 643/tcp #SANity sanity 643/udp #SANity dwr 644/tcp dwr 644/udp pssc 645/tcp pssc 645/udp ldp 646/tcp ldp 646/udp -dhcp-failover 647/tcp #DHCP Failover -dhcp-failover 647/udp #DHCP Failover -rrp 648/tcp #Registry Registrar Protocol (RRP) -rrp 648/udp #Registry Registrar Protocol (RRP) -cadview-3d 649/tcp #Cadview-3d - streaming 3d models over the internet -cadview-3d 649/udp #Cadview-3d - streaming 3d models over the internet +dhcp-failover 647/tcp #DHCP Failover +dhcp-failover 647/udp #DHCP Failover +rrp 648/tcp #Registry Registrar Protocol (RRP) +rrp 648/udp #Registry Registrar Protocol (RRP) +cadview-3d 649/tcp #Cadview-3d - streaming 3d models over the internet +cadview-3d 649/udp #Cadview-3d - streaming 3d models over the internet obex 650/tcp obex 650/udp ieee-mms 651/tcp #IEEE MMS ieee-mms 651/udp #IEEE MMS hello-port 652/tcp hello-port 652/udp repscmd 653/tcp repscmd 653/udp aodv 654/tcp #Ad-Hoc On-Demand Distance Vector Routing Protocol aodv 654/udp #Ad-Hoc On-Demand Distance Vector Routing Protocol tinc 655/tcp tinc 655/udp spmp 656/tcp spmp 656/udp rmc 657/tcp rmc 657/udp tenfold 658/tcp tenfold 658/udp -mac-srvr-admin 660/tcp #MacOS Server Admin -mac-srvr-admin 660/udp #MacOS Server Admin -hap 661/tcp -hap 661/udp -pftp 662/tcp -pftp 662/udp -purenoise 663/tcp #PureNoise -purenoise 663/udp #PureNoise -asf-secure-rmcp 664/tcp #ASF Secure Remote Management and Control Protocol -asf-secure-rmcp 664/udp #ASF Secure Remote Management and Control Protocol -sun-dr 665/tcp #Sun DR -sun-dr 665/udp #Sun DR +mac-srvr-admin 660/tcp #MacOS Server Admin +mac-srvr-admin 660/udp #MacOS Server Admin +hap 661/tcp +hap 661/udp +pftp 662/tcp +pftp 662/udp +purenoise 663/tcp #PureNoise +purenoise 663/udp #PureNoise +asf-secure-rmcp 664/tcp #ASF Secure Remote Management and Control Protocol +asf-secure-rmcp 664/udp #ASF Secure Remote Management and Control Protocol +sun-dr 665/tcp #Sun DR +sun-dr 665/udp #Sun DR mdqs 666/tcp mdqs 666/udp #PROBLEMS!=============================================== doom 666/tcp #doom Id Software doom 666/udp #doom Id Software #PROBLEMS!=============================================== -disclose 667/tcp #campaign contribution disclosures - SDR Technologies -disclose 667/udp #campaign contribution disclosures - SDR Technologies -mecomm 668/tcp -mecomm 668/udp -meregister 669/tcp -meregister 669/udp -vacdsm-sws 670/tcp -vacdsm-sws 670/udp -vacdsm-app 671/tcp -vacdsm-app 671/udp -vpps-qua 672/tcp -vpps-qua 672/udp -cimplex 673/tcp -cimplex 673/udp +disclose 667/tcp #campaign contribution disclosures - SDR Technologies +disclose 667/udp #campaign contribution disclosures - SDR Technologies +mecomm 668/tcp +mecomm 668/udp +meregister 669/tcp +meregister 669/udp +vacdsm-sws 670/tcp +vacdsm-sws 670/udp +vacdsm-app 671/tcp +vacdsm-app 671/udp +vpps-qua 672/tcp +vpps-qua 672/udp +cimplex 673/tcp +cimplex 673/udp acap 674/tcp #Application Configuration Access Protocol acap 674/udp #Application Configuration Access Protocol dctp 675/tcp dctp 675/udp vpps-via 676/tcp #VPPS Via vpps-via 676/udp #VPPS Via vpp 677/tcp #Virtual Presence Protocol vpp 677/udp #Virtual Presence Protocol ggf-ncp 678/tcp #GNU Generation Foundation NCP ggf-ncp 678/udp #GNU Generation Foundation NCP -mrm 679/tcp -mrm 679/udp +mrm 679/tcp +mrm 679/udp entrust-aaas 680/tcp entrust-aaas 680/udp entrust-aams 681/tcp entrust-aams 681/udp -xfr 682/tcp -xfr 682/udp -corba-iiop 683/tcp #CORBA IIOP -corba-iiop 683/udp #CORBA IIOP +xfr 682/tcp +xfr 682/udp +corba-iiop 683/tcp #CORBA IIOP +corba-iiop 683/udp #CORBA IIOP corba-iiop-ssl 684/tcp #CORBA IIOP SSL corba-iiop-ssl 684/udp #CORBA IIOP SSL mdc-portmapper 685/tcp #MDC Port Mapper mdc-portmapper 685/udp #MDC Port Mapper -hcp-wismar 686/tcp #Hardware Control Protocol Wismar -hcp-wismar 686/udp #Hardware Control Protocol Wismar +hcp-wismar 686/tcp #Hardware Control Protocol Wismar +hcp-wismar 686/udp #Hardware Control Protocol Wismar asipregistry 687/tcp asipregistry 687/udp -realm-rusd 688/tcp #ApplianceWare management protocol -realm-rusd 688/udp #ApplianceWare management protocol -nmap 689/tcp -nmap 689/udp -vatp 690/tcp #Velazquez Application Transfer Protocol -vatp 690/udp #Velazquez Application Transfer Protocol +realm-rusd 688/tcp #ApplianceWare management protocol +realm-rusd 688/udp #ApplianceWare management protocol +nmap 689/tcp +nmap 689/udp +vatp 690/tcp #Velazquez Application Transfer Protocol +vatp 690/udp #Velazquez Application Transfer Protocol msexch-routing 691/tcp #MS Exchange Routing msexch-routing 691/udp #MS Exchange Routing hyperwave-isp 692/tcp #Hyperwave-ISP hyperwave-isp 692/udp #Hyperwave-ISP -connendp 693/tcp -connendp 693/udp -ha-cluster 694/tcp -ha-cluster 694/udp -ieee-mms-ssl 695/tcp -ieee-mms-ssl 695/udp -rushd 696/tcp -rushd 696/udp -uuidgen 697/tcp -uuidgen 697/udp -olsr 698/tcp -olsr 698/udp -accessnetwork 699/tcp #Access Network -accessnetwork 699/udp #Access Network -epp 700/tcp #Extensible Provisioning Protocol -epp 700/udp #Extensible Provisioning Protocol -lmp 701/tcp #Link Management Protocol (LMP) -lmp 701/udp #Link Management Protocol (LMP) -iris-beep 702/tcp #IRIS over BEEP -iris-beep 702/udp #IRIS over BEEP +connendp 693/tcp +connendp 693/udp +ha-cluster 694/tcp +ha-cluster 694/udp +ieee-mms-ssl 695/tcp +ieee-mms-ssl 695/udp +rushd 696/tcp +rushd 696/udp +uuidgen 697/tcp +uuidgen 697/udp +olsr 698/tcp +olsr 698/udp +accessnetwork 699/tcp #Access Network +accessnetwork 699/udp #Access Network +epp 700/tcp #Extensible Provisioning Protocol +epp 700/udp #Extensible Provisioning Protocol +lmp 701/tcp #Link Management Protocol (LMP) +lmp 701/udp #Link Management Protocol (LMP) +iris-beep 702/tcp #IRIS over BEEP +iris-beep 702/udp #IRIS over BEEP elcsd 704/tcp #errlog copy/server daemon elcsd 704/udp #errlog copy/server daemon -agentx 705/tcp #AgentX -agentx 705/udp #AgentX -silc 706/tcp -silc 706/udp -borland-dsj 707/tcp #Borland DSJ -borland-dsj 707/udp #Borland DSJ +agentx 705/tcp #AgentX +agentx 705/udp #AgentX +silc 706/tcp +silc 706/udp +borland-dsj 707/tcp #Borland DSJ +borland-dsj 707/udp #Borland DSJ entrustmanager 709/tcp #EntrustManager entrustmanager 709/udp #EntrustManager -entrust-ash 710/tcp #Entrust Administration Service Handler -entrust-ash 710/udp #Entrust Administration Service Handler -cisco-tdp 711/tcp #Cisco TDP -cisco-tdp 711/udp #Cisco TDP -tbrpf 712/tcp -tbrpf 712/udp +entrust-ash 710/tcp #Entrust Administration Service Handler +entrust-ash 710/udp #Entrust Administration Service Handler +cisco-tdp 711/tcp #Cisco TDP +cisco-tdp 711/udp #Cisco TDP +tbrpf 712/tcp +tbrpf 712/udp iris-xpc 713/tcp #IRIS over XPC iris-xpc 713/udp #IRIS over XPC iris-xpcs 714/tcp #IRIS over XPCS iris-xpcs 714/udp #IRIS over XPCS iris-lwz 715/tcp iris-lwz 715/udp netviewdm1 729/tcp #IBM NetView DM/6000 Server/Client netviewdm1 729/udp #IBM NetView DM/6000 Server/Client netviewdm2 730/tcp #IBM NetView DM/6000 send/tcp netviewdm2 730/udp #IBM NetView DM/6000 send/tcp netviewdm3 731/tcp #IBM NetView DM/6000 receive/tcp netviewdm3 731/udp #IBM NetView DM/6000 receive/tcp netgw 741/tcp netgw 741/udp netrcs 742/tcp #Network based Rev. Cont. Sys. netrcs 742/udp #Network based Rev. Cont. Sys. flexlm 744/tcp #Flexible License Manager flexlm 744/udp #Flexible License Manager fujitsu-dev 747/tcp #Fujitsu Device Control fujitsu-dev 747/udp #Fujitsu Device Control ris-cm 748/tcp #Russell Info Sci Calendar Manager ris-cm 748/udp #Russell Info Sci Calendar Manager kerberos-adm 749/tcp #Kerberos administration (v5) kerberos-adm 749/udp #Kerberos administration (v5) kerberos-iv 750/udp kdc # Kerberos (v4) kerberos-iv 750/tcp kdc # Kerberos (v4) #PROBLEMS!======================================================== #rfile 750/tcp #loadav 750/udp #PROBLEMS!======================================================== kerberos_master 751/tcp # Kerberos `kadmin' (v4) kerberos_master 751/udp # Kerberos `kadmin' (v4) #PROBLEMS!======================================================== pump 751/tcp pump 751/udp #PROBLEMS!======================================================== qrh 752/tcp qrh 752/udp rrh 753/tcp rrh 753/udp krb_prop 754/tcp krb5_prop # kerberos/v5 server propagation #PROBLEMS!======================================================== tell 754/tcp #send #PROBLEMS!======================================================== tell 754/udp #send nlogin 758/tcp nlogin 758/udp con 759/tcp con 759/udp krbupdate 760/tcp kreg # Kerberos (v4) registration #PROBLEMS!======================================================== ns 760/tcp #PROBLEMS!======================================================== ns 760/udp kpasswd 761/tcp kpwd # Kerberos (v4) "passwd" #PROBLEMS!======================================================== rxe 761/tcp #PROBLEMS!======================================================== rxe 761/udp quotad 762/tcp quotad 762/udp cycleserv 763/tcp cycleserv 763/udp omserv 764/tcp omserv 764/udp webster 765/tcp webster 765/udp phonebook 767/tcp #phone phonebook 767/udp #phone vid 769/tcp vid 769/udp cadlock 770/tcp cadlock 770/udp rtip 771/tcp rtip 771/udp cycleserv2 772/tcp cycleserv2 772/udp submit 773/tcp notify 773/udp rpasswd 774/tcp acmaint_dbd 774/udp entomb 775/tcp acmaint_transd 775/udp wpages 776/tcp wpages 776/udp multiling-http 777/tcp #Multiling HTTP multiling-http 777/udp #Multiling HTTP wpgs 780/tcp wpgs 780/udp mdbs_daemon 800/tcp mdbs_daemon 800/udp device 801/tcp device 801/udp fcp-udp 810/tcp #FCP fcp-udp 810/udp #FCP Datagram itm-mcell-s 828/tcp itm-mcell-s 828/udp pkix-3-ca-ra 829/tcp #PKIX-3 CA/RA -pkix-3-ca-ra 829/udp #PKIX-3 CA/RA -netconf-ssh 830/tcp #NETCONF over SSH -netconf-ssh 830/udp #NETCONF over SSH -netconf-beep 831/tcp #NETCONF over BEEP -netconf-beep 831/udp #NETCONF over BEEP -netconfsoaphttp 832/tcp #NETCONF for SOAP over HTTPS -netconfsoaphttp 832/udp #NETCONF for SOAP over HTTPS -netconfsoapbeep 833/tcp #NETCONF for SOAP over BEEP -netconfsoapbeep 833/udp #NETCONF for SOAP over BEEP -dhcp-failover2 847/tcp #dhcp-failover 2 -dhcp-failover2 847/udp #dhcp-failover 2 -gdoi 848/tcp -gdoi 848/udp -iscsi 860/tcp -iscsi 860/udp -owamp-control 861/tcp -owamp-control 861/udp +pkix-3-ca-ra 829/udp #PKIX-3 CA/RA +netconf-ssh 830/tcp #NETCONF over SSH +netconf-ssh 830/udp #NETCONF over SSH +netconf-beep 831/tcp #NETCONF over BEEP +netconf-beep 831/udp #NETCONF over BEEP +netconfsoaphttp 832/tcp #NETCONF for SOAP over HTTPS +netconfsoaphttp 832/udp #NETCONF for SOAP over HTTPS +netconfsoapbeep 833/tcp #NETCONF for SOAP over BEEP +netconfsoapbeep 833/udp #NETCONF for SOAP over BEEP +dhcp-failover2 847/tcp #dhcp-failover 2 +dhcp-failover2 847/udp #dhcp-failover 2 +gdoi 848/tcp +gdoi 848/udp +iscsi 860/tcp +iscsi 860/udp +owamp-control 861/tcp +owamp-control 861/udp supfilesrv 871/tcp # for SUP rsync 873/tcp rsync 873/udp -iclcnet-locate 886/tcp #ICL coNETion locate server -iclcnet-locate 886/udp #ICL coNETion locate server -iclcnet_svinfo 887/tcp #ICL coNETion server info -iclcnet_svinfo 887/udp #ICL coNETion server info +iclcnet-locate 886/tcp #ICL coNETion locate server +iclcnet-locate 886/udp #ICL coNETion locate server +iclcnet_svinfo 887/tcp #ICL coNETion server info +iclcnet_svinfo 887/udp #ICL coNETion server info accessbuilder 888/tcp accessbuilder 888/udp -omginitialrefs 900/tcp #OMG Initial Refs -omginitialrefs 900/udp #OMG Initial Refs +omginitialrefs 900/tcp #OMG Initial Refs +omginitialrefs 900/udp #OMG Initial Refs swat 901/tcp # samba web configuration tool -smpnameres 901/tcp -smpnameres 901/udp -ideafarm-chat 902/tcp -ideafarm-chat 902/udp -ideafarm-catch 903/tcp -ideafarm-catch 903/udp -kink 910/tcp #Kerberized Internet Negotiation of Keys (KINK) -kink 910/udp #Kerberized Internet Negotiation of Keys (KINK) -xact-backup 911/tcp -xact-backup 911/udp -apex-mesh 912/tcp #APEX relay-relay service -apex-mesh 912/udp #APEX relay-relay service -apex-edge 913/tcp #APEX endpoint-relay service -apex-edge 913/udp #APEX endpoint-relay service +smpnameres 901/tcp +smpnameres 901/udp +ideafarm-chat 902/tcp +ideafarm-chat 902/udp +ideafarm-catch 903/tcp +ideafarm-catch 903/udp +kink 910/tcp #Kerberized Internet Negotiation of Keys (KINK) +kink 910/udp #Kerberized Internet Negotiation of Keys (KINK) +xact-backup 911/tcp +xact-backup 911/udp +apex-mesh 912/tcp #APEX relay-relay service +apex-mesh 912/udp #APEX relay-relay service +apex-edge 913/tcp #APEX endpoint-relay service +apex-edge 913/udp #APEX endpoint-relay service rndc 953/tcp # named's rndc control socket ftps-data 989/tcp # ftp protocol, data, over TLS/SSL ftps-data 989/udp ftps 990/tcp # ftp protocol, control, over TLS/SSL ftps 990/udp nas 991/tcp #Netnews Administration System nas 991/udp #Netnews Administration System telnets 992/tcp # telnet protocol over TLS/SSL telnets 992/udp imaps 993/tcp # imap4 protocol over TLS/SSL imaps 993/udp ircs 994/tcp # irc protocol over TLS/SSL ircs 994/udp pop3s 995/tcp spop3 # pop3 protocol over TLS/SSL pop3s 995/udp spop3 vsinet 996/tcp vsinet 996/udp maitrd 997/tcp maitrd 997/udp busboy 998/tcp puparp 998/udp garcon 999/tcp applix 999/udp #Applix ac puprouter 999/tcp puprouter 999/udp cadlock2 1000/tcp cadlock2 1000/udp surf 1010/tcp surf 1010/udp -exp1 1021/tcp #RFC3692-style Experiment 1 (*) [RFC4727] -exp1 1021/udp #RFC3692-style Experiment 1 (*) [RFC4727] -exp2 1022/tcp #RFC3692-style Experiment 2 (*) [RFC4727] -exp2 1022/udp #RFC3692-style Experiment 2 (*) [RFC4727] +exp1 1021/tcp #RFC3692-style Experiment 1 (*) [RFC4727] +exp1 1021/udp #RFC3692-style Experiment 1 (*) [RFC4727] +exp2 1022/tcp #RFC3692-style Experiment 2 (*) [RFC4727] +exp2 1022/udp #RFC3692-style Experiment 2 (*) [RFC4727] # # REGISTERED PORT NUMBERS # blackjack 1025/tcp #network blackjack blackjack 1025/udp #network blackjack iad1 1030/tcp #BBN IAD iad1 1030/udp #BBN IAD iad2 1031/tcp #BBN IAD iad2 1031/udp #BBN IAD iad3 1032/tcp #BBN IAD iad3 1032/udp #BBN IAD nim 1058/tcp nim 1058/udp nimreg 1059/tcp nimreg 1059/udp instl_boots 1067/tcp #Installation Bootstrap Proto. Serv. instl_boots 1067/udp #Installation Bootstrap Proto. Serv. instl_bootc 1068/tcp #Installation Bootstrap Proto. Cli. instl_bootc 1068/udp #Installation Bootstrap Proto. Cli. socks 1080/tcp socks 1080/udp ansoft-lm-1 1083/tcp #Anasoft License Manager ansoft-lm-1 1083/udp #Anasoft License Manager ansoft-lm-2 1084/tcp #Anasoft License Manager ansoft-lm-2 1084/udp #Anasoft License Manager webobjects 1085/tcp #Web Objects webobjects 1085/udp #Web Objects kpop 1109/tcp #Unofficial kpop 1109/udp #Unofficial nfsd-status 1110/tcp #Cluster status info nfsd-keepalive 1110/udp #Client status info supfiledbg 1127/tcp # for SUP nfa 1155/tcp #Network File Access nfa 1155/udp #Network File Access cisco-ipsla 1167/sctp #Cisco IP SLAs Control Protocol cisco-ipsla 1167/tcp #Cisco IP SLAs Control Protocol cisco-ipsla 1167/udp #Cisco IP SLAs Control Protocol skkserv 1178/tcp #SKK (kanji input) openvpn 1194/tcp #OpenVPN openvpn 1194/udp #OpenVPN lupa 1212/tcp lupa 1212/udp nerv 1222/tcp #SNI R&D network nerv 1222/udp #SNI R&D network hermes 1248/tcp hermes 1248/udp healthd 1281/tcp #healthd healthd 1281/udp #healthd alta-ana-lm 1346/tcp #Alta Analytics License Manager alta-ana-lm 1346/udp #Alta Analytics License Manager bbn-mmc 1347/tcp #multi media conferencing bbn-mmc 1347/udp #multi media conferencing bbn-mmx 1348/tcp #multi media conferencing bbn-mmx 1348/udp #multi media conferencing sbook 1349/tcp #Registration Network Protocol sbook 1349/udp #Registration Network Protocol editbench 1350/tcp #Registration Network Protocol editbench 1350/udp #Registration Network Protocol equationbuilder 1351/tcp #Digital Tool Works (MIT) equationbuilder 1351/udp #Digital Tool Works (MIT) lotusnote 1352/tcp #Lotus Note lotusnote 1352/udp #Lotus Note relief 1353/tcp #Relief Consulting relief 1353/udp #Relief Consulting rightbrain 1354/tcp #RightBrain Software rightbrain 1354/udp #RightBrain Software intuitive-edge 1355/tcp #Intuitive Edge intuitive-edge 1355/udp #Intuitive Edge cuillamartin 1356/tcp #CuillaMartin Company cuillamartin 1356/udp #CuillaMartin Company pegboard 1357/tcp #Electronic PegBoard pegboard 1357/udp #Electronic PegBoard connlcli 1358/tcp connlcli 1358/udp ftsrv 1359/tcp ftsrv 1359/udp mimer 1360/tcp mimer 1360/udp linx 1361/tcp linx 1361/udp timeflies 1362/tcp timeflies 1362/udp ndm-requester 1363/tcp #Network DataMover Requester ndm-requester 1363/udp #Network DataMover Requester ndm-server 1364/tcp #Network DataMover Server ndm-server 1364/udp #Network DataMover Server adapt-sna 1365/tcp #Network Software Associates adapt-sna 1365/udp #Network Software Associates netware-csp 1366/tcp #Novell NetWare Comm Service Platform netware-csp 1366/udp #Novell NetWare Comm Service Platform dcs 1367/tcp dcs 1367/udp screencast 1368/tcp screencast 1368/udp gv-us 1369/tcp #GlobalView to Unix Shell gv-us 1369/udp #GlobalView to Unix Shell us-gv 1370/tcp #Unix Shell to GlobalView us-gv 1370/udp #Unix Shell to GlobalView fc-cli 1371/tcp #Fujitsu Config Protocol fc-cli 1371/udp #Fujitsu Config Protocol fc-ser 1372/tcp #Fujitsu Config Protocol fc-ser 1372/udp #Fujitsu Config Protocol chromagrafx 1373/tcp chromagrafx 1373/udp molly 1374/tcp #EPI Software Systems molly 1374/udp #EPI Software Systems bytex 1375/tcp bytex 1375/udp ibm-pps 1376/tcp #IBM Person to Person Software ibm-pps 1376/udp #IBM Person to Person Software cichlid 1377/tcp #Cichlid License Manager cichlid 1377/udp #Cichlid License Manager elan 1378/tcp #Elan License Manager elan 1378/udp #Elan License Manager dbreporter 1379/tcp #Integrity Solutions dbreporter 1379/udp #Integrity Solutions telesis-licman 1380/tcp #Telesis Network License Manager telesis-licman 1380/udp #Telesis Network License Manager apple-licman 1381/tcp #Apple Network License Manager apple-licman 1381/udp #Apple Network License Manager #udt_os 1382/tcp #udt_os 1382/udp gwha 1383/tcp #GW Hannaway Network License Manager gwha 1383/udp #GW Hannaway Network License Manager os-licman 1384/tcp #Objective Solutions License Manager os-licman 1384/udp #Objective Solutions License Manager atex_elmd 1385/tcp #Atex Publishing License Manager atex_elmd 1385/udp #Atex Publishing License Manager checksum 1386/tcp #CheckSum License Manager checksum 1386/udp #CheckSum License Manager cadsi-lm 1387/tcp #Computer Aided Design Software Inc LM cadsi-lm 1387/udp #Computer Aided Design Software Inc LM objective-dbc 1388/tcp #Objective Solutions DataBase Cache objective-dbc 1388/udp #Objective Solutions DataBase Cache iclpv-dm 1389/tcp #Document Manager iclpv-dm 1389/udp #Document Manager iclpv-sc 1390/tcp #Storage Controller iclpv-sc 1390/udp #Storage Controller iclpv-sas 1391/tcp #Storage Access Server iclpv-sas 1391/udp #Storage Access Server iclpv-pm 1392/tcp #Print Manager iclpv-pm 1392/udp #Print Manager iclpv-nls 1393/tcp #Network Log Server iclpv-nls 1393/udp #Network Log Server iclpv-nlc 1394/tcp #Network Log Client iclpv-nlc 1394/udp #Network Log Client iclpv-wsm 1395/tcp #PC Workstation Manager software iclpv-wsm 1395/udp #PC Workstation Manager software dvl-activemail 1396/tcp #DVL Active Mail dvl-activemail 1396/udp #DVL Active Mail audio-activmail 1397/tcp #Audio Active Mail audio-activmail 1397/udp #Audio Active Mail video-activmail 1398/tcp #Video Active Mail video-activmail 1398/udp #Video Active Mail cadkey-licman 1399/tcp #Cadkey License Manager cadkey-licman 1399/udp #Cadkey License Manager cadkey-tablet 1400/tcp #Cadkey Tablet Daemon cadkey-tablet 1400/udp #Cadkey Tablet Daemon goldleaf-licman 1401/tcp #Goldleaf License Manager goldleaf-licman 1401/udp #Goldleaf License Manager prm-sm-np 1402/tcp #Prospero Resource Manager prm-sm-np 1402/udp #Prospero Resource Manager prm-nm-np 1403/tcp #Prospero Resource Manager prm-nm-np 1403/udp #Prospero Resource Manager igi-lm 1404/tcp #Infinite Graphics License Manager igi-lm 1404/udp #Infinite Graphics License Manager ibm-res 1405/tcp #IBM Remote Execution Starter ibm-res 1405/udp #IBM Remote Execution Starter netlabs-lm 1406/tcp #NetLabs License Manager netlabs-lm 1406/udp #NetLabs License Manager dbsa-lm 1407/tcp #DBSA License Manager dbsa-lm 1407/udp #DBSA License Manager sophia-lm 1408/tcp #Sophia License Manager sophia-lm 1408/udp #Sophia License Manager here-lm 1409/tcp #Here License Manager here-lm 1409/udp #Here License Manager hiq 1410/tcp #HiQ License Manager hiq 1410/udp #HiQ License Manager af 1411/tcp #AudioFile af 1411/udp #AudioFile innosys 1412/tcp innosys 1412/udp innosys-acl 1413/tcp innosys-acl 1413/udp ibm-mqseries 1414/tcp #IBM MQSeries ibm-mqseries 1414/udp #IBM MQSeries dbstar 1415/tcp dbstar 1415/udp novell-lu6.2 1416/tcp #Novell LU6.2 novell-lu6.2 1416/udp #Novell LU6.2 timbuktu-srv1 1417/tcp #Timbuktu Service 1 Port timbuktu-srv1 1417/udp #Timbuktu Service 1 Port timbuktu-srv2 1418/tcp #Timbuktu Service 2 Port timbuktu-srv2 1418/udp #Timbuktu Service 2 Port timbuktu-srv3 1419/tcp #Timbuktu Service 3 Port timbuktu-srv3 1419/udp #Timbuktu Service 3 Port timbuktu-srv4 1420/tcp #Timbuktu Service 4 Port timbuktu-srv4 1420/udp #Timbuktu Service 4 Port gandalf-lm 1421/tcp #Gandalf License Manager gandalf-lm 1421/udp #Gandalf License Manager autodesk-lm 1422/tcp #Autodesk License Manager autodesk-lm 1422/udp #Autodesk License Manager essbase 1423/tcp #Essbase Arbor Software essbase 1423/udp #Essbase Arbor Software hybrid 1424/tcp #Hybrid Encryption Protocol hybrid 1424/udp #Hybrid Encryption Protocol zion-lm 1425/tcp #Zion Software License Manager zion-lm 1425/udp #Zion Software License Manager sas-1 1426/tcp #Satellite-data Acquisition System 1 sas-1 1426/udp #Satellite-data Acquisition System 1 mloadd 1427/tcp #mloadd monitoring tool mloadd 1427/udp #mloadd monitoring tool informatik-lm 1428/tcp #Informatik License Manager informatik-lm 1428/udp #Informatik License Manager nms 1429/tcp #Hypercom NMS nms 1429/udp #Hypercom NMS tpdu 1430/tcp #Hypercom TPDU tpdu 1430/udp #Hypercom TPDU rgtp 1431/tcp #Reverse Gossip Transport rgtp 1431/udp #Reverse Gossip Transport blueberry-lm 1432/tcp #Blueberry Software License Manager blueberry-lm 1432/udp #Blueberry Software License Manager ms-sql-s 1433/tcp #Microsoft-SQL-Server ms-sql-s 1433/udp #Microsoft-SQL-Server ms-sql-m 1434/tcp #Microsoft-SQL-Monitor ms-sql-m 1434/udp #Microsoft-SQL-Monitor ibm-cics 1435/tcp ibm-cics 1435/udp sas-2 1436/tcp #Satellite-data Acquisition System 2 sas-2 1436/udp #Satellite-data Acquisition System 2 tabula 1437/tcp tabula 1437/udp eicon-server 1438/tcp #Eicon Security Agent/Server eicon-server 1438/udp #Eicon Security Agent/Server eicon-x25 1439/tcp #Eicon X25/SNA Gateway eicon-x25 1439/udp #Eicon X25/SNA Gateway eicon-slp 1440/tcp #Eicon Service Location Protocol eicon-slp 1440/udp #Eicon Service Location Protocol cadis-1 1441/tcp #Cadis License Management cadis-1 1441/udp #Cadis License Management cadis-2 1442/tcp #Cadis License Management cadis-2 1442/udp #Cadis License Management ies-lm 1443/tcp #Integrated Engineering Software ies-lm 1443/udp #Integrated Engineering Software marcam-lm 1444/tcp #Marcam License Management marcam-lm 1444/udp #Marcam License Management proxima-lm 1445/tcp #Proxima License Manager proxima-lm 1445/udp #Proxima License Manager ora-lm 1446/tcp #Optical Research Associates License Manager ora-lm 1446/udp #Optical Research Associates License Manager apri-lm 1447/tcp #Applied Parallel Research LM apri-lm 1447/udp #Applied Parallel Research LM oc-lm 1448/tcp #OpenConnect License Manager oc-lm 1448/udp #OpenConnect License Manager peport 1449/tcp peport 1449/udp dwf 1450/tcp #Tandem Distributed Workbench Facility dwf 1450/udp #Tandem Distributed Workbench Facility infoman 1451/tcp #IBM Information Management infoman 1451/udp #IBM Information Management gtegsc-lm 1452/tcp #GTE Government Systems License Man gtegsc-lm 1452/udp #GTE Government Systems License Man genie-lm 1453/tcp #Genie License Manager genie-lm 1453/udp #Genie License Manager interhdl_elmd 1454/tcp #interHDL License Manager interhdl_elmd 1454/udp #interHDL License Manager esl-lm 1455/tcp #ESL License Manager esl-lm 1455/udp #ESL License Manager dca 1456/tcp dca 1456/udp valisys-lm 1457/tcp #Valisys License Manager valisys-lm 1457/udp #Valisys License Manager nrcabq-lm 1458/tcp #Nichols Research Corp. nrcabq-lm 1458/udp #Nichols Research Corp. proshare1 1459/tcp #Proshare Notebook Application proshare1 1459/udp #Proshare Notebook Application proshare2 1460/tcp #Proshare Notebook Application proshare2 1460/udp #Proshare Notebook Application ibm_wrless_lan 1461/tcp #IBM Wireless LAN ibm_wrless_lan 1461/udp #IBM Wireless LAN world-lm 1462/tcp #World License Manager world-lm 1462/udp #World License Manager nucleus 1463/tcp nucleus 1463/udp msl_lmd 1464/tcp #MSL License Manager msl_lmd 1464/udp #MSL License Manager pipes 1465/tcp #Pipes Platform pipes 1465/udp #Pipes Platform mfarlin@peerlogic.com oceansoft-lm 1466/tcp #Ocean Software License Manager oceansoft-lm 1466/udp #Ocean Software License Manager csdmbase 1467/tcp csdmbase 1467/udp csdm 1468/tcp csdm 1468/udp aal-lm 1469/tcp #Active Analysis Limited License Manager aal-lm 1469/udp #Active Analysis Limited License Manager uaiact 1470/tcp #Universal Analytics uaiact 1470/udp #Universal Analytics csdmbase 1471/tcp csdmbase 1471/udp csdm 1472/tcp csdm 1472/udp openmath 1473/tcp openmath 1473/udp telefinder 1474/tcp telefinder 1474/udp taligent-lm 1475/tcp #Taligent License Manager taligent-lm 1475/udp #Taligent License Manager clvm-cfg 1476/tcp clvm-cfg 1476/udp ms-sna-server 1477/tcp ms-sna-server 1477/udp ms-sna-base 1478/tcp ms-sna-base 1478/udp dberegister 1479/tcp dberegister 1479/udp pacerforum 1480/tcp pacerforum 1480/udp airs 1481/tcp airs 1481/udp miteksys-lm 1482/tcp #Miteksys License Manager miteksys-lm 1482/udp #Miteksys License Manager afs 1483/tcp #AFS License Manager afs 1483/udp #AFS License Manager confluent 1484/tcp #Confluent License Manager confluent 1484/udp #Confluent License Manager lansource 1485/tcp lansource 1485/udp nms_topo_serv 1486/tcp nms_topo_serv 1486/udp localinfosrvr 1487/tcp localinfosrvr 1487/udp docstor 1488/tcp docstor 1488/udp dmdocbroker 1489/tcp dmdocbroker 1489/udp insitu-conf 1490/tcp insitu-conf 1490/udp anynetgateway 1491/tcp anynetgateway 1491/udp stone-design-1 1492/tcp stone-design-1 1492/udp netmap_lm 1493/tcp netmap_lm 1493/udp ica 1494/tcp ica 1494/udp cvc 1495/tcp cvc 1495/udp liberty-lm 1496/tcp liberty-lm 1496/udp rfx-lm 1497/tcp rfx-lm 1497/udp watcom-sql 1498/tcp watcom-sql 1498/udp fhc 1499/tcp #Federico Heinz Consultora fhc 1499/udp #Federico Heinz Consultora vlsi-lm 1500/tcp #VLSI License Manager vlsi-lm 1500/udp #VLSI License Manager sas-3 1501/tcp #Satellite-data Acquisition System 3 sas-3 1501/udp #Satellite-data Acquisition System 3 shivadiscovery 1502/tcp #Shiva shivadiscovery 1502/udp #Shiva imtc-mcs 1503/tcp #Databeam imtc-mcs 1503/udp #Databeam evb-elm 1504/tcp #EVB Software Engineering License Manager evb-elm 1504/udp #EVB Software Engineering License Manager funkproxy 1505/tcp #Funk Software, Inc. funkproxy 1505/udp #Funk Software, Inc. utcd 1506/tcp #Universal Time daemon (utcd) utcd 1506/udp #Universal Time daemon (utcd) symplex 1507/tcp symplex 1507/udp diagmond 1508/tcp diagmond 1508/udp robcad-lm 1509/tcp #Robcad, Ltd. License Manager robcad-lm 1509/udp #Robcad, Ltd. License Manager mvx-lm 1510/tcp #Midland Valley Exploration Ltd. Lic. Man. mvx-lm 1510/udp #Midland Valley Exploration Ltd. Lic. Man. 3l-l1 1511/tcp 3l-l1 1511/udp wins 1512/tcp #Microsoft's Windows Internet Name Service wins 1512/udp #Microsoft's Windows Internet Name Service fujitsu-dtc 1513/tcp #Fujitsu Systems Business of America, Inc fujitsu-dtc 1513/udp #Fujitsu Systems Business of America, Inc fujitsu-dtcns 1514/tcp #Fujitsu Systems Business of America, Inc fujitsu-dtcns 1514/udp #Fujitsu Systems Business of America, Inc ifor-protocol 1515/tcp ifor-protocol 1515/udp vpad 1516/tcp #Virtual Places Audio data vpad 1516/udp #Virtual Places Audio data vpac 1517/tcp #Virtual Places Audio control vpac 1517/udp #Virtual Places Audio control vpvd 1518/tcp #Virtual Places Video data vpvd 1518/udp #Virtual Places Video data vpvc 1519/tcp #Virtual Places Video control vpvc 1519/udp #Virtual Places Video control atm-zip-office 1520/tcp #atm zip office atm-zip-office 1520/udp #atm zip office ncube-lm 1521/tcp #nCube License Manager ncube-lm 1521/udp #nCube License Manager rna-lm 1522/tcp #Ricardo North America License Manager rna-lm 1522/udp #Ricardo North America License Manager cichild-lm 1523/tcp cichild-lm 1523/udp ingreslock 1524/tcp #ingres ingreslock 1524/udp #ingres prospero-np 1525/tcp #Prospero Directory Service non-priv prospero-np 1525/udp #Prospero Directory Service non-priv #PROBLEMS!======================================================== orasrv 1525/tcp #oracle orasrv 1525/udp #oracle #PROBLEMS!======================================================== pdap-np 1526/tcp #Prospero Data Access Prot non-priv pdap-np 1526/udp #Prospero Data Access Prot non-priv tlisrv 1527/tcp #oracle tlisrv 1527/udp #oracle mciautoreg 1528/tcp mciautoreg 1528/udp support 1529/tcp prmsd gnatsd # cygnus bug tracker coauthor 1529/tcp #oracle coauthor 1529/udp #oracle rap-service 1530/tcp rap-service 1530/udp rap-listen 1531/tcp rap-listen 1531/udp miroconnect 1532/tcp miroconnect 1532/udp virtual-places 1533/tcp #Virtual Places Software virtual-places 1533/udp #Virtual Places Software micromuse-lm 1534/tcp micromuse-lm 1534/udp ampr-info 1535/tcp ampr-info 1535/udp ampr-inter 1536/tcp ampr-inter 1536/udp sdsc-lm 1537/tcp sdsc-lm 1537/udp 3ds-lm 1538/tcp 3ds-lm 1538/udp intellistor-lm 1539/tcp #Intellistor License Manager intellistor-lm 1539/udp #Intellistor License Manager rds 1540/tcp rds 1540/udp rds2 1541/tcp rds2 1541/udp gridgen-elmd 1542/tcp gridgen-elmd 1542/udp simba-cs 1543/tcp simba-cs 1543/udp aspeclmd 1544/tcp aspeclmd 1544/udp vistium-share 1545/tcp vistium-share 1545/udp abbaccuray 1546/tcp abbaccuray 1546/udp laplink 1547/tcp laplink 1547/udp axon-lm 1548/tcp #Axon License Manager axon-lm 1548/udp #Axon License Manager shivahose 1549/tcp #Shiva Hose shivasound 1549/udp #Shiva Sound 3m-image-lm 1550/tcp #Image Storage license manager 3M Company 3m-image-lm 1550/udp #Image Storage license manager 3M Company hecmtl-db 1551/tcp hecmtl-db 1551/udp pciarray 1552/tcp pciarray 1552/udp issd 1600/tcp issd 1600/udp # IMPORTANT NOTE: Ports 1645/1646 are the traditional radius ports used by # many vendors without obtaining official IANA assignment. The official # assignment is now ports 1812/1813 and users are encouraged to migrate # when possible to these new ports. #radius 1645/udp #RADIUS authentication protocol (old) #radacct 1646/udp #RADIUS accounting protocol (old) nkd 1650/tcp nkd 1650/udp shiva_confsrvr 1651/tcp shiva_confsrvr 1651/udp xnmp 1652/tcp xnmp 1652/udp netview-aix-1 1661/tcp netview-aix-1 1661/udp netview-aix-2 1662/tcp netview-aix-2 1662/udp netview-aix-3 1663/tcp netview-aix-3 1663/udp netview-aix-4 1664/tcp netview-aix-4 1664/udp netview-aix-5 1665/tcp netview-aix-5 1665/udp netview-aix-6 1666/tcp netview-aix-6 1666/udp netview-aix-7 1667/tcp netview-aix-7 1667/udp netview-aix-8 1668/tcp netview-aix-8 1668/udp netview-aix-9 1669/tcp netview-aix-9 1669/udp netview-aix-10 1670/tcp netview-aix-10 1670/udp netview-aix-11 1671/tcp netview-aix-11 1671/udp netview-aix-12 1672/tcp netview-aix-12 1672/udp l2f 1701/tcp #l2f l2f 1701/udp #l2f l2tp 1701/tcp #Layer 2 Tunnelling Protocol l2tp 1701/udp #Layer 2 Tunnelling Protocol pptp 1723/tcp #Point-to-point tunnelling protocol # IMPORTANT NOTE: See comments for ports 1645/1646 when using older equipment radius 1812/udp #RADIUS authentication protocol (IANA sanctioned) radacct 1813/udp #RADIUS accounting protocol (IANA sanctioned) licensedaemon 1986/tcp #cisco license management licensedaemon 1986/udp #cisco license management tr-rsrb-p1 1987/tcp #cisco RSRB Priority 1 port tr-rsrb-p1 1987/udp #cisco RSRB Priority 1 port tr-rsrb-p2 1988/tcp #cisco RSRB Priority 2 port tr-rsrb-p2 1988/udp #cisco RSRB Priority 2 port tr-rsrb-p3 1989/tcp #cisco RSRB Priority 3 port tr-rsrb-p3 1989/udp #cisco RSRB Priority 3 port #PROBLEMS!=================================================== mshnet 1989/tcp #MHSnet system mshnet 1989/udp #MHSnet system #PROBLEMS!=================================================== stun-p1 1990/tcp #cisco STUN Priority 1 port stun-p1 1990/udp #cisco STUN Priority 1 port stun-p2 1991/tcp #cisco STUN Priority 2 port stun-p2 1991/udp #cisco STUN Priority 2 port stun-p3 1992/tcp #cisco STUN Priority 3 port stun-p3 1992/udp #cisco STUN Priority 3 port #PROBLEMS!=================================================== ipsendmsg 1992/tcp ipsendmsg 1992/udp #PROBLEMS!=================================================== snmp-tcp-port 1993/tcp #cisco SNMP TCP port snmp-tcp-port 1993/udp #cisco SNMP TCP port stun-port 1994/tcp #cisco serial tunnel port stun-port 1994/udp #cisco serial tunnel port perf-port 1995/tcp #cisco perf port perf-port 1995/udp #cisco perf port tr-rsrb-port 1996/tcp #cisco Remote SRB port tr-rsrb-port 1996/udp #cisco Remote SRB port gdp-port 1997/tcp #cisco Gateway Discovery Protocol gdp-port 1997/udp #cisco Gateway Discovery Protocol x25-svc-port 1998/tcp #cisco X.25 service (XOT) x25-svc-port 1998/udp #cisco X.25 service (XOT) tcp-id-port 1999/tcp #cisco identification port tcp-id-port 1999/udp #cisco identification port callbook 2000/tcp callbook 2000/udp dc 2001/tcp wizard 2001/udp #curry globe 2002/tcp globe 2002/udp cfingerd 2003/tcp #GNU finger mailbox 2004/tcp emce 2004/udp #CCWS mm conf berknet 2005/tcp oracle 2005/udp invokator 2006/tcp raid-cc 2006/udp #raid dectalk 2007/tcp raid-am 2007/udp conf 2008/tcp terminaldb 2008/udp news 2009/tcp whosockami 2009/udp search 2010/tcp pipe_server 2010/udp raid-cc 2011/tcp #raid servserv 2011/udp ttyinfo 2012/tcp raid-ac 2012/udp raid-am 2013/tcp raid-cd 2013/udp troff 2014/tcp raid-sf 2014/udp cypress 2015/tcp raid-cs 2015/udp bootserver 2016/tcp bootserver 2016/udp cypress-stat 2017/tcp bootclient 2017/udp terminaldb 2018/tcp rellpack 2018/udp whosockami 2019/tcp about 2019/udp xinupageserver 2020/tcp xinupageserver 2020/udp servexec 2021/tcp xinuexpansion1 2021/udp down 2022/tcp xinuexpansion2 2022/udp xinuexpansion3 2023/tcp xinuexpansion3 2023/udp xinuexpansion4 2024/tcp xinuexpansion4 2024/udp ellpack 2025/tcp xribs 2025/udp scrabble 2026/tcp scrabble 2026/udp shadowserver 2027/tcp shadowserver 2027/udp submitserver 2028/tcp submitserver 2028/udp device2 2030/tcp device2 2030/udp blackboard 2032/tcp blackboard 2032/udp glogger 2033/tcp glogger 2033/udp scoremgr 2034/tcp scoremgr 2034/udp imsldoc 2035/tcp imsldoc 2035/udp objectmanager 2038/tcp objectmanager 2038/udp lam 2040/tcp lam 2040/udp interbase 2041/tcp interbase 2041/udp isis 2042/tcp isis 2042/udp isis-bcast 2043/tcp isis-bcast 2043/udp rimsl 2044/tcp rimsl 2044/udp cdfunc 2045/tcp cdfunc 2045/udp sdfunc 2046/tcp sdfunc 2046/udp #dls 2047/tcp #dls 2047/udp dls-monitor 2048/tcp dls-monitor 2048/udp nfsd 2049/sctp nfs # NFS server daemon nfsd 2049/tcp nfs # NFS server daemon nfsd 2049/udp nfs # NFS server daemon #PROBLEMS!============================================================= #shilp 2049/tcp #shilp 2049/udp #PROBLEMS!============================================================= dlsrpn 2065/tcp #Data Link Switch Read Port Number dlsrpn 2065/udp #Data Link Switch Read Port Number dlswpn 2067/tcp #Data Link Switch Write Port Number dlswpn 2067/udp #Data Link Switch Write Port Number zephyr-clt 2103/udp #Zephyr serv-hm connection zephyr-hm 2104/udp #Zephyr hostmanager #PROBLEMS!============================================================= #zephyr-hm-srv 2105/udp #Zephyr hm-serv connection #PROBLEMS!============================================================= eklogin 2105/tcp #Kerberos (v4) encrypted rlogin eklogin 2105/udp #Kerberos (v4) encrypted rlogin ekshell 2106/tcp #Kerberos (v4) encrypted rshell ekshell 2106/udp #Kerberos (v4) encrypted rshell rkinit 2108/tcp #Kerberos (v4) remote initialization rkinit 2108/udp #Kerberos (v4) remote initialization ats 2201/tcp #Advanced Training System Program ats 2201/udp #Advanced Training System Program hpssd 2207/tcp #HP Status and Services hpssd 2207/udp #HP Status and Services hpiod 2208/tcp #HP I/O Backend hpiod 2208/udp #HP I/O Backend rcip-itu 2225/sctp #Resource Connection Initiation Protocol rcip-itu 2225/tcp #Resource Connection Initiation Protocol ivs-video 2232/tcp #IVS Video default ivs-video 2232/udp #IVS Video default ivsd 2241/tcp #IVS Daemon ivsd 2241/udp #IVS Daemon pehelp 2307/tcp pehelp 2307/udp cvspserver 2401/tcp #CVS network server cvspserver 2401/udp #CVS network server venus 2430/tcp #venus venus 2430/udp #venus venus-se 2431/tcp #venus-se venus-se 2431/udp #venus-se codasrv 2432/tcp #codasrv codasrv 2432/udp #codasrv codasrv-se 2433/tcp #codasrv-se codasrv-se 2433/udp #codasrv-se rtsserv 2500/tcp #Resource Tracking system server rtsserv 2500/udp #Resource Tracking system server rtsclient 2501/tcp #Resource Tracking system client rtsclient 2501/udp #Resource Tracking system client hp-3000-telnet 2564/tcp #HP 3000 NS/VT block mode telnet zebrasrv 2600/tcp #zebra service zebra 2601/tcp #zebra vty ripd 2602/tcp #RIPd vty ripngd 2603/tcp #RIPngd vty ospfd 2604/tcp #OSPFd vty bgpd 2605/tcp #BGPd vty ospf6d 2606/tcp #OSPF6d vty dict 2628/tcp #RFC 2229 dict 2628/udp #RFC 2229 listen 2766/tcp #System V listener port www-dev 2784/tcp #world wide web - development www-dev 2784/udp #world wide web - development m2ua 2904/sctp #M2UA m2ua 2904/tcp #M2UA m2ua 2904/udp #M2UA m3ua 2905/sctp #M3UA m3ua 2905/tcp #M3UA megaco-h248 2944/sctp #Megaco-H.248 text megaco-h248 2944/tcp #Megaco H-248 megaco-h248 2944/udp #Megaco H-248 h248-binary 2945/sctp #Megaco/H.248 binary h248-binary 2945/tcp #H248 Binary h248-binary 2945/udp #H248 Binary eppc 3031/tcp #Remote AppleEvents/PPC Toolbox eppc 3031/udp #Remote AppleEvents/PPC Toolbox NSWS 3049/tcp NSWS 3049/udp gds_db 3050/tcp #InterBase Database Remote Protocol gds_db 3050/udp #InterBase Database Remote Protocol sj3 3086/tcp #SJ3 (kanji input) itu-bicc-stc 3097/sctp #ITU-T Q.1902.1/Q.2150.3 vmodem 3141/tcp vmodem 3141/udp iscsi-target 3260/tcp # iSCSI port iscsi-target 3260/udp # iSCSI port ccmail 3264/tcp #cc:mail/lotus ccmail 3264/udp #cc:mail/lotus mysql 3306/tcp #MySQL mysql 3306/udp #MySQL dec-notes 3333/tcp #DEC Notes dec-notes 3333/udp #DEC Notes rdp 3389/tcp #Microsoft Remote Desktop Protocol bmap 3421/tcp #Bull Apprise portmapper bmap 3421/udp #Bull Apprise portmapper prsvp 3455/tcp #RSVP Port prsvp 3455/udp rsvp-encap #RSVP Port vat 3456/tcp #VAT default data vat 3456/udp #VAT default data vat-control 3457/tcp #VAT default control vat-control 3457/udp #VAT default control nut 3493/tcp #Network UPS Tools nut 3493/udp #Network UPS Tools m2pa 3565/sctp #M2PA m2pa 3565/tcp #M2PA tsp 3653/tcp #Tunnel Setup Protocol tsp 3653/udp #Tunnel Setup Protocol svn 3690/tcp #Subversion svn 3690/udp #Subversion asap 3863/sctp #asap sctp asap 3863/tcp #asap tcp port asap 3863/udp #asap udp port asap-tls 3864/sctp #asap-sctp/tls asap-tls 3864/tcp #asap/tls tcp port diameter 3868/tcp #DIAMETER diameter 3868/sctp #DIAMETER udt_os 3900/tcp #Unidata UDT OS udt_os 3900/udp #Unidata UDT OS mapper-nodemgr 3984/tcp #MAPPER network node manager mapper-nodemgr 3984/udp #MAPPER network node manager mapper-mapethd 3985/tcp #MAPPER TCP/IP server mapper-mapethd 3985/udp #MAPPER TCP/IP server mapper-ws_ethd 3986/tcp #MAPPER workstation server mapper-ws_ethd 3986/udp #MAPPER workstation server netcheque 4008/tcp #NetCheque accounting netcheque 4008/udp #NetCheque accounting lockd 4045/udp # NFS lock daemon/manager lockd 4045/tcp nuts_dem 4132/tcp #NUTS Daemon nuts_dem 4132/udp #NUTS Daemon nuts_bootp 4133/tcp #NUTS Bootp Server nuts_bootp 4133/udp #NUTS Bootp Server sieve 4190/tcp #ManageSieve Protocol sieve 4190/udp #ManageSieve Protocol rwhois 4321/tcp #Remote Who Is rwhois 4321/udp #Remote Who Is unicall 4343/tcp unicall 4343/udp epmd 4369/tcp #Erlang Port Mapper Daemon epmd 4369/udp #Erlang Port Mapper Daemon krb524 4444/tcp krb524 4444/udp # PROBLEM krb524 assigned the port, # PROBLEM nv used it without an assignment nv-video 4444/tcp #NV Video default nv-video 4444/udp #NV Video default sae-urn 4500/tcp sae-urn 4500/udp fax 4557/tcp #FAX transmission service hylafax 4559/tcp #HylaFAX client-server protocol rfa 4672/tcp #remote file access server rfa 4672/udp #remote file access server ipfix 4739/sctp #IP Flow Info Export ipfix 4739/tcp #IP Flow Info Export ipfix 4739/udp #IP Flow Info Export ipfixs 4740/sctp #ipfix protocol over DTLS ipfixs 4740/tcp #ipfix protocol over TLS ipfixs 4740/udp #ipfix protocol over DTLS commplex-main 5000/tcp commplex-main 5000/udp commplex-link 5001/tcp commplex-link 5001/udp rfe 5002/tcp #radio free ethernet rfe 5002/udp #radio free ethernet telelpathstart 5010/tcp telelpathstart 5010/udp telelpathattack 5011/tcp telelpathattack 5011/udp mmcc 5050/tcp #multimedia conference control tool mmcc 5050/udp #multimedia conference control tool sds 5059/tcp #SIP Directory Services sds 5059/udp #SIP Directory Services sip 5060/tcp #Session Initialization Protocol (VoIP) sip 5060/udp #Session Initialization Protocol (VoIP) sip-tls 5061/tcp #SIP over TLS sip-tls 5061/udp #SIP over TLS car 5090/sctp #Candidate AR cxtp 5091/sctp #Context Transfer Protocol rmonitor_secure 5145/tcp rmonitor_secure 5145/udp aol 5190/tcp #America-Online aol 5190/udp #America-Online aol-1 5191/tcp #AmericaOnline1 aol-1 5191/udp #AmericaOnline1 aol-2 5192/tcp #AmericaOnline2 aol-2 5192/udp #AmericaOnline2 aol-3 5193/tcp #AmericaOnline3 aol-3 5193/udp #AmericaOnline3 xmpp-client 5222/tcp #XMPP Client Connection xmpp-client 5222/udp #XMPP Client Connection padl2sim 5236/tcp padl2sim 5236/udp xmpp-server 5269/tcp #XMPP Server Connection xmpp-server 5269/udp #XMPP Server Connection hacl-hb 5300/tcp # HA cluster heartbeat hacl-hb 5300/udp # HA cluster heartbeat hacl-gs 5301/tcp # HA cluster general services hacl-gs 5301/udp # HA cluster general services hacl-cfg 5302/tcp # HA cluster configuration hacl-cfg 5302/udp # HA cluster configuration hacl-probe 5303/tcp # HA cluster probing hacl-probe 5303/udp # HA cluster probing hacl-local 5304/tcp hacl-local 5304/udp hacl-test 5305/tcp hacl-test 5305/udp cfengine 5308/tcp cfengine 5308/udp mdns 5353/tcp #Multicast DNS mdns 5353/udp #Multicast DNS postgresql 5432/tcp #PostgreSQL Database postgresql 5432/udp #PostgreSQL Database vami 5480/tcp #VMware Appliance Management Interface, HTTPS-like vami 5480/udp #VMware Appliance Management Interface, HTTPS-like rplay 5555/udp amqp 5672/sctp #AMQP amqp 5672/tcp #AMQP amqp 5672/udp #AMQP v5ua 5675/sctp #V5UA application port v5ua 5675/tcp #V5UA application port v5ua 5675/udp #V5UA application port canna 5680/tcp #Canna (Japanese Input) proshareaudio 5713/tcp #proshare conf audio proshareaudio 5713/udp #proshare conf audio prosharevideo 5714/tcp #proshare conf video prosharevideo 5714/udp #proshare conf video prosharedata 5715/tcp #proshare conf data prosharedata 5715/udp #proshare conf data prosharerequest 5716/tcp #proshare conf request prosharerequest 5716/udp #proshare conf request prosharenotify 5717/tcp #proshare conf notify prosharenotify 5717/udp #proshare conf notify couchdb 5984/tcp #CouchDB database server couchdb 5984/udp #CouchDB database server cvsup 5999/tcp #CVSup file transfer/John Polstra/FreeBSD x11 6000/tcp #6000-6063 are assigned to X Window System x11 6000/udp x11-ssh 6010/tcp #Unofficial name, for convenience x11-ssh 6010/udp softcm 6110/tcp #HP SoftBench CM softcm 6110/udp #HP SoftBench CM spc 6111/tcp #HP SoftBench Sub-Process Control spc 6111/udp #HP SoftBench Sub-Process Control meta-corp 6141/tcp #Meta Corporation License Manager meta-corp 6141/udp #Meta Corporation License Manager aspentec-lm 6142/tcp #Aspen Technology License Manager aspentec-lm 6142/udp #Aspen Technology License Manager watershed-lm 6143/tcp #Watershed License Manager watershed-lm 6143/udp #Watershed License Manager statsci1-lm 6144/tcp #StatSci License Manager - 1 statsci1-lm 6144/udp #StatSci License Manager - 1 statsci2-lm 6145/tcp #StatSci License Manager - 2 statsci2-lm 6145/udp #StatSci License Manager - 2 lonewolf-lm 6146/tcp #Lone Wolf Systems License Manager lonewolf-lm 6146/udp #Lone Wolf Systems License Manager montage-lm 6147/tcp #Montage License Manager montage-lm 6147/udp #Montage License Manager ricardo-lm 6148/tcp #Ricardo North America License Manager ricardo-lm 6148/udp #Ricardo North America License Manager sge_qmaster 6444/tcp #Grid Engine Qmaster Service sge_qmaster 6444/udp #Grid Engine Qmaster Service sge_execd 6445/tcp #Grid Engine Execution Service sge_execd 6445/udp #Grid Engine Execution Service xdsxdm 6558/tcp xdsxdm 6558/udp sane-port 6566/tcp #Scanner Access Now Easy (SANE) Control Port sane-port 6566/udp #Scanner Access Now Easy (SANE) Control Port ircd 6667/tcp #Internet Relay Chat (unofficial) +ircs-u 6697/tcp #Internet Relay Chat over TLS/SSL frc-hp 6704/sctp #ForCES HP (High Priority) channel frc-mp 6705/sctp #ForCES MP (Medium Priority) channel frc-lp 6706/sctp #ForCES LP (Low priority) channel acmsoda 6969/tcp acmsoda 6969/udp afs3-fileserver 7000/tcp #file server itself afs3-fileserver 7000/udp #file server itself afs3-callback 7001/tcp #callbacks to cache managers afs3-callback 7001/udp #callbacks to cache managers afs3-prserver 7002/tcp #users & groups database afs3-prserver 7002/udp #users & groups database afs3-vlserver 7003/tcp #volume location database afs3-vlserver 7003/udp #volume location database afs3-kaserver 7004/tcp #AFS/Kerberos authentication service afs3-kaserver 7004/udp #AFS/Kerberos authentication service afs3-volser 7005/tcp #volume management server afs3-volser 7005/udp #volume management server afs3-errors 7006/tcp #error interpretation service afs3-errors 7006/udp #error interpretation service afs3-bos 7007/tcp #basic overseer process afs3-bos 7007/udp #basic overseer process afs3-update 7008/tcp #server-to-server updater afs3-update 7008/udp #server-to-server updater afs3-rmtsys 7009/tcp #remote cache manager service afs3-rmtsys 7009/udp #remote cache manager service afs3-resserver 7010/tcp #MR-AFS residence server afs3-resserver 7010/udp #MR-AFS residence server ups-onlinet 7010/tcp #onlinet uninterruptable power supplies ups-onlinet 7010/udp #onlinet uninterruptable power supplies afs3-remio 7011/tcp #MR-AFS remote IO server afs3-remio 7011/udp #MR-AFS remote IO server font-service 7100/tcp #X Font Service font-service 7100/udp #X Font Service fodms 7200/tcp #FODMS FLIP fodms 7200/udp #FODMS FLIP dlip 7201/tcp dlip 7201/udp simco 7626/sctp #SImple Middlebox COnfiguration (SIMCO) simco 7626/tcp #SImple Middlebox COnfiguration (SIMCO) Server ftp-proxy 8021/tcp # FTP proxy pim 8471/sctp #PIM over Reliable Transport pim 8471/tcp #PIM over Reliable Transport natd 8668/divert # Network Address Translation lcs-ap 9082/sctp #LCS Application Protocol aurora 9084/sctp #IBM AURORA Performance Visualizer aurora 9084/tcp #IBM AURORA Performance Visualizer aurora 9084/udp #IBM AURORA Performance Visualizer jetdirect 9100/tcp #HP JetDirect card git 9418/tcp #git pack transfer service git 9418/udp #git pack transfer service man 9535/tcp man 9535/udp sd 9876/tcp #Session Director sd 9876/udp #Session Director iua 9900/sctp #IUA iua 9900/tcp #IUA iua 9900/udp #IUA enrp 9901/sctp #enrp server channel enrp 9901/udp #enrp server channel enrp-tls 9902/sctp #enrp/tls server channel amanda 10080/tcp #Dump server control amanda 10080/udp #Dump server control amandaidx 10082/tcp #Amanda indexing amidxtape 10083/tcp #Amanda tape indexing wmereceiving 11997/sctp #WorldMailExpress wmedistribution 11998/sctp #WorldMailExpress wmereporting 11999/sctp #WorldMailExpress sua 14001/sctp #SUA sua 14001/tcp #SUA isode-dua 17007/tcp isode-dua 17007/udp biimenu 18000/tcp #Beckman Instruments, Inc. biimenu 18000/udp #Beckman Instruments, Inc. nfsrdma 20049/sctp #Network File System (NFS) over RDMA nfsrdma 20049/tcp #Network File System (NFS) over RDMA nfsrdma 20049/udp #Network File System (NFS) over RDMA wnn4 22273/tcp wnn6 #Wnn4 (Japanese input) wnn4_Cn 22289/tcp wnn6_Cn #Wnn4 (Chinese input) wnn4_Kr 22305/tcp wnn6_Kr #Wnn4 (Korean input) wnn4_Tw 22321/tcp wnn6_Tw #Wnn4 (Taiwanse input) wnn6_DS 26208/tcp #Wnn6 (Dserver) sgsap 29118/sctp #SGsAP in 3GPP sbcap 29168/sctp #SBcAP in 3GPP iuhsctpassoc 29169/sctp #HNBAP and RUA Common Association s1-control 36412/sctp #S1-Control Plane (3GPP) x2-control 36422/sctp #X2-Control Plane (3GPP) dbbrowse 47557/tcp #Databeam Corporation dbbrowse 47557/udp #Databeam Corporation Index: user/ngie/stable-10-libnv/gnu/usr.bin/Makefile =================================================================== --- user/ngie/stable-10-libnv/gnu/usr.bin/Makefile (revision 292856) +++ user/ngie/stable-10-libnv/gnu/usr.bin/Makefile (revision 292857) @@ -1,55 +1,57 @@ # $FreeBSD$ .include SUBDIR= ${_binutils} \ ${_cc} \ dialog \ diff \ diff3 \ ${_dtc} \ ${_gdb} \ ${_gperf} \ grep \ ${_groff} \ ${_rcs} \ sdiff \ ${_tests} \ ${_texinfo} +SUBDIR_DEPEND_gdb= ${_binutils} + .if ${MK_CXX} != "no" _gperf= gperf .if ${MK_GROFF} != "no" _groff= groff .endif .endif .if ${MK_GPL_DTC} != "no" _dtc= dtc .endif .if ${MK_INFO} != "no" _texinfo= texinfo .endif .if ${MK_RCS} != "no" _rcs= rcs .endif .if ${MK_TESTS} != "no" _tests= tests .endif .if ${MK_BINUTILS} != "no" _binutils= binutils .endif .if ${MK_GCC} != "no" _cc= cc .endif .if ${MK_GDB} != "no" _gdb= gdb .endif SUBDIR_PARALLEL= .include Index: user/ngie/stable-10-libnv/include/netdb.h =================================================================== --- user/ngie/stable-10-libnv/include/netdb.h (revision 292856) +++ user/ngie/stable-10-libnv/include/netdb.h (revision 292857) @@ -1,293 +1,293 @@ /*- * Copyright (c) 1980, 1983, 1988, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * - * Portions Copyright (c) 1993 by Digital Equipment Corporation. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies, and that * the name of Digital Equipment Corporation not be used in advertising or * publicity pertaining to distribution of the document or software without * specific, written prior permission. * * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. * - * --Copyright-- */ /* * @(#)netdb.h 8.1 (Berkeley) 6/2/93 * From: Id: netdb.h,v 8.9 1996/11/19 08:39:29 vixie Exp $ * $FreeBSD$ */ #ifndef _NETDB_H_ #define _NETDB_H_ #include #include #ifndef _SIZE_T_DECLARED typedef __size_t size_t; #define _SIZE_T_DECLARED #endif #ifndef _SOCKLEN_T_DECLARED typedef __socklen_t socklen_t; #define _SOCKLEN_T_DECLARED #endif #ifndef _UINT32_T_DECLARED typedef __uint32_t uint32_t; #define _UINT32_T_DECLARED #endif #ifndef _PATH_HEQUIV # define _PATH_HEQUIV "/etc/hosts.equiv" #endif #define _PATH_HOSTS "/etc/hosts" #define _PATH_NETWORKS "/etc/networks" #define _PATH_PROTOCOLS "/etc/protocols" #define _PATH_SERVICES "/etc/services" #define _PATH_SERVICES_DB "/var/db/services.db" #define h_errno (*__h_errno()) /* * Structures returned by network data base library. All addresses are * supplied in host order, and returned in network order (suitable for * use in system calls). */ struct hostent { char *h_name; /* official name of host */ char **h_aliases; /* alias list */ int h_addrtype; /* host address type */ int h_length; /* length of address */ char **h_addr_list; /* list of addresses from name server */ #define h_addr h_addr_list[0] /* address, for backward compatibility */ }; struct netent { char *n_name; /* official name of net */ char **n_aliases; /* alias list */ int n_addrtype; /* net address type */ uint32_t n_net; /* network # */ }; struct servent { char *s_name; /* official service name */ char **s_aliases; /* alias list */ int s_port; /* port # */ char *s_proto; /* protocol to use */ }; struct protoent { char *p_name; /* official protocol name */ char **p_aliases; /* alias list */ int p_proto; /* protocol # */ }; struct addrinfo { int ai_flags; /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */ - int ai_family; /* PF_xxx */ + int ai_family; /* AF_xxx */ int ai_socktype; /* SOCK_xxx */ int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ socklen_t ai_addrlen; /* length of ai_addr */ char *ai_canonname; /* canonical name for hostname */ struct sockaddr *ai_addr; /* binary address */ struct addrinfo *ai_next; /* next structure in linked list */ }; /* * Error return codes from gethostbyname() and gethostbyaddr() * (left in h_errno). */ #define NETDB_INTERNAL -1 /* see errno */ #define NETDB_SUCCESS 0 /* no problem */ #define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found */ #define TRY_AGAIN 2 /* Non-Authoritative Host not found, or SERVERFAIL */ #define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */ #define NO_DATA 4 /* Valid name, no data record of requested type */ #define NO_ADDRESS NO_DATA /* no address, look for MX record */ /* * Error return codes from getaddrinfo() */ #if 0 /* obsoleted */ #define EAI_ADDRFAMILY 1 /* address family for hostname not supported */ #endif #define EAI_AGAIN 2 /* temporary failure in name resolution */ #define EAI_BADFLAGS 3 /* invalid value for ai_flags */ #define EAI_FAIL 4 /* non-recoverable failure in name resolution */ #define EAI_FAMILY 5 /* ai_family not supported */ #define EAI_MEMORY 6 /* memory allocation failure */ #if 0 /* obsoleted */ #define EAI_NODATA 7 /* no address associated with hostname */ #endif #define EAI_NONAME 8 /* hostname nor servname provided, or not known */ #define EAI_SERVICE 9 /* servname not supported for ai_socktype */ #define EAI_SOCKTYPE 10 /* ai_socktype not supported */ #define EAI_SYSTEM 11 /* system error returned in errno */ #define EAI_BADHINTS 12 /* invalid value for hints */ #define EAI_PROTOCOL 13 /* resolved protocol is unknown */ #define EAI_OVERFLOW 14 /* argument buffer overflow */ #define EAI_MAX 15 /* * Flag values for getaddrinfo() */ #define AI_PASSIVE 0x00000001 /* get address to use bind() */ #define AI_CANONNAME 0x00000002 /* fill ai_canonname */ #define AI_NUMERICHOST 0x00000004 /* prevent host name resolution */ #define AI_NUMERICSERV 0x00000008 /* prevent service name resolution */ /* valid flags for addrinfo (not a standard def, apps should not use it) */ #define AI_MASK \ (AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST | AI_NUMERICSERV | \ - AI_ADDRCONFIG) + AI_ADDRCONFIG | AI_ALL | AI_V4MAPPED) #define AI_ALL 0x00000100 /* IPv6 and IPv4-mapped (with AI_V4MAPPED) */ #define AI_V4MAPPED_CFG 0x00000200 /* accept IPv4-mapped if kernel supports */ #define AI_ADDRCONFIG 0x00000400 /* only if any address is assigned */ #define AI_V4MAPPED 0x00000800 /* accept IPv4-mapped IPv6 address */ /* special recommended flags for getipnodebyname */ #define AI_DEFAULT (AI_V4MAPPED_CFG | AI_ADDRCONFIG) /* * Constants for getnameinfo() */ #define NI_MAXHOST 1025 #define NI_MAXSERV 32 /* * Flag values for getnameinfo() */ #define NI_NOFQDN 0x00000001 #define NI_NUMERICHOST 0x00000002 #define NI_NAMEREQD 0x00000004 #define NI_NUMERICSERV 0x00000008 #define NI_DGRAM 0x00000010 #if 0 /* obsolete */ #define NI_WITHSCOPEID 0x00000020 #endif /* * Scope delimit character */ #define SCOPE_DELIMITER '%' __BEGIN_DECLS void endhostent(void); void endnetent(void); void endprotoent(void); void endservent(void); #if __BSD_VISIBLE || (__POSIX_VISIBLE && __POSIX_VISIBLE <= 200112) struct hostent *gethostbyaddr(const void *, socklen_t, int); struct hostent *gethostbyname(const char *); #endif struct hostent *gethostent(void); struct netent *getnetbyaddr(uint32_t, int); struct netent *getnetbyname(const char *); struct netent *getnetent(void); struct protoent *getprotobyname(const char *); struct protoent *getprotobynumber(int); struct protoent *getprotoent(void); struct servent *getservbyname(const char *, const char *); struct servent *getservbyport(int, const char *); struct servent *getservent(void); void sethostent(int); /* void sethostfile(const char *); */ void setnetent(int); void setprotoent(int); int getaddrinfo(const char *, const char *, const struct addrinfo *, struct addrinfo **); int getnameinfo(const struct sockaddr *, socklen_t, char *, size_t, char *, size_t, int); void freeaddrinfo(struct addrinfo *); const char *gai_strerror(int); void setservent(int); #if __BSD_VISIBLE void endnetgrent(void); void freehostent(struct hostent *); int gethostbyaddr_r(const void *, socklen_t, int, struct hostent *, char *, size_t, struct hostent **, int *); int gethostbyname_r(const char *, struct hostent *, char *, size_t, struct hostent **, int *); struct hostent *gethostbyname2(const char *, int); int gethostbyname2_r(const char *, int, struct hostent *, char *, size_t, struct hostent **, int *); int gethostent_r(struct hostent *, char *, size_t, struct hostent **, int *); struct hostent *getipnodebyaddr(const void *, size_t, int, int *); struct hostent *getipnodebyname(const char *, int, int, int *); int getnetbyaddr_r(uint32_t, int, struct netent *, char *, size_t, struct netent**, int *); int getnetbyname_r(const char *, struct netent *, char *, size_t, struct netent **, int *); int getnetent_r(struct netent *, char *, size_t, struct netent **, int *); int getnetgrent(char **, char **, char **); int getprotobyname_r(const char *, struct protoent *, char *, size_t, struct protoent **); int getprotobynumber_r(int, struct protoent *, char *, size_t, struct protoent **); int getprotoent_r(struct protoent *, char *, size_t, struct protoent **); int getservbyname_r(const char *, const char *, struct servent *, char *, size_t, struct servent **); int getservbyport_r(int, const char *, struct servent *, char *, size_t, struct servent **); int getservent_r(struct servent *, char *, size_t, struct servent **); void herror(const char *); const char *hstrerror(int); int innetgr(const char *, const char *, const char *, const char *); void setnetgrent(const char *); #endif /* * PRIVATE functions specific to the FreeBSD implementation */ /* DO NOT USE THESE, THEY ARE SUBJECT TO CHANGE AND ARE NOT PORTABLE!!! */ int * __h_errno(void); __END_DECLS #endif /* !_NETDB_H_ */ Index: user/ngie/stable-10-libnv/lib/libc/gen/lockf.c =================================================================== --- user/ngie/stable-10-libnv/lib/libc/gen/lockf.c (revision 292856) +++ user/ngie/stable-10-libnv/lib/libc/gen/lockf.c (revision 292857) @@ -1,79 +1,84 @@ /* $NetBSD: lockf.c,v 1.3 2008/04/28 20:22:59 martin Exp $ */ /*- * Copyright (c) 1997 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by Klaus Klein. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include #include #include "un-namespace.h" +#include "libc_private.h" int lockf(int filedes, int function, off_t size) { struct flock fl; int cmd; fl.l_start = 0; fl.l_len = size; fl.l_whence = SEEK_CUR; switch (function) { case F_ULOCK: cmd = F_SETLK; fl.l_type = F_UNLCK; break; case F_LOCK: cmd = F_SETLKW; fl.l_type = F_WRLCK; break; case F_TLOCK: cmd = F_SETLK; fl.l_type = F_WRLCK; break; case F_TEST: fl.l_type = F_WRLCK; - if (_fcntl(filedes, F_GETLK, &fl) == -1) + if (((int (*)(int, int, ...)) + __libc_interposing[INTERPOS_fcntl])(filedes, F_GETLK, &fl) + == -1) return (-1); - if (fl.l_type == F_UNLCK || (fl.l_sysid == 0 && fl.l_pid == getpid())) + if (fl.l_type == F_UNLCK || (fl.l_sysid == 0 && + fl.l_pid == getpid())) return (0); errno = EAGAIN; return (-1); /* NOTREACHED */ default: errno = EINVAL; return (-1); /* NOTREACHED */ } - return (_fcntl(filedes, cmd, &fl)); + return (((int (*)(int, int, ...)) + __libc_interposing[INTERPOS_fcntl])(filedes, cmd, &fl)); } Index: user/ngie/stable-10-libnv/lib/libc/net/getaddrinfo.3 =================================================================== --- user/ngie/stable-10-libnv/lib/libc/net/getaddrinfo.3 (revision 292856) +++ user/ngie/stable-10-libnv/lib/libc/net/getaddrinfo.3 (revision 292857) @@ -1,459 +1,499 @@ .\" $KAME: getaddrinfo.3,v 1.36 2005/01/05 03:23:05 itojun Exp $ .\" $OpenBSD: getaddrinfo.3,v 1.35 2004/12/21 03:40:31 jaredy Exp $ .\" .\" Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000, 2001 Internet Software Consortium. .\" .\" Permission to use, copy, modify, and distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above .\" copyright notice and this permission notice appear in all copies. .\" .\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH .\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY .\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, .\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM .\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE .\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. .\" .\" $FreeBSD$ .\" -.Dd October 5, 2015 +.Dd December 21, 2015 .Dt GETADDRINFO 3 .Os .Sh NAME .Nm getaddrinfo , .Nm freeaddrinfo .Nd socket address structure to host and service name .Sh SYNOPSIS .In sys/types.h .In sys/socket.h .In netdb.h .Ft int .Fo getaddrinfo .Fa "const char *hostname" "const char *servname" .Fa "const struct addrinfo *hints" "struct addrinfo **res" .Fc .Ft void .Fn freeaddrinfo "struct addrinfo *ai" .Sh DESCRIPTION The .Fn getaddrinfo function is used to get a list of .Tn IP addresses and port numbers for host .Fa hostname and service .Fa servname . It is a replacement for and provides more flexibility than the .Xr gethostbyname 3 and .Xr getservbyname 3 functions. .Pp The .Fa hostname and .Fa servname arguments are either pointers to NUL-terminated strings or the null pointer. An acceptable value for .Fa hostname is either a valid host name or a numeric host address string consisting of a dotted decimal IPv4 address or an IPv6 address. The .Fa servname is either a decimal port number or a service name listed in .Xr services 5 . At least one of .Fa hostname and .Fa servname must be non-null. .Pp .Fa hints is an optional pointer to a .Li struct addrinfo , as defined by .Aq Pa netdb.h : .Bd -literal struct addrinfo { int ai_flags; /* input flags */ - int ai_family; /* protocol family for socket */ + int ai_family; /* address family for socket */ int ai_socktype; /* socket type */ int ai_protocol; /* protocol for socket */ socklen_t ai_addrlen; /* length of socket-address */ struct sockaddr *ai_addr; /* socket-address for socket */ char *ai_canonname; /* canonical name for service location */ struct addrinfo *ai_next; /* pointer to next in list */ }; .Ed .Pp This structure can be used to provide hints concerning the type of socket that the caller supports or wishes to use. The caller can supply the following structure elements in .Fa hints : .Bl -tag -width "ai_socktypeXX" .It Fa ai_family -The protocol family that should be used. +The address family that should be used. When .Fa ai_family is set to -.Dv PF_UNSPEC , -it means the caller will accept any protocol family supported by the +.Dv AF_UNSPEC , +it means the caller will accept any address family supported by the operating system. .It Fa ai_socktype Denotes the type of socket that is wanted: .Dv SOCK_STREAM , .Dv SOCK_DGRAM , or .Dv SOCK_RAW . When .Fa ai_socktype is zero the caller will accept any socket type. .It Fa ai_protocol Indicates which transport protocol is desired, .Dv IPPROTO_UDP or .Dv IPPROTO_TCP . If .Fa ai_protocol is zero the caller will accept any protocol. .It Fa ai_flags The .Fa ai_flags field to which the .Fa hints parameter points shall be set to zero or be the bitwise-inclusive OR of one or more of the values .Dv AI_ADDRCONFIG , +.Dv AI_ALL , .Dv AI_CANONNAME , .Dv AI_NUMERICHOST , -.Dv AI_NUMERICSERV +.Dv AI_NUMERICSERV , +.Dv AI_PASSIVE and -.Dv AI_PASSIVE . +.Dv AI_V4MAPPED . .Bl -tag -width "AI_CANONNAMEXX" .It Dv AI_ADDRCONFIG If the .Dv AI_ADDRCONFIG bit is set, IPv4 addresses shall be returned only if an IPv4 address is configured on the local system, and IPv6 addresses shall be returned only if an IPv6 address is configured on the local system. +.It Dv AI_ALL +If the +.Dv AI_ALL +flag is used with the +.Dv AI_V4MAPPED +flag, then +.Fn getaddrinfo +shall return all matching IPv6 and IPv4 addresses. +.Pp +For example, when using the DNS, queries are made for both AAAA records and A records, and +.Fn getaddrinfo +returns the combined results of both queries. +Any IPv4 addresses found are returned as IPv4-mapped IPv6 addresses. +.Pp +The +.Dv AI_ALL +flag without the +.Dv AI_V4MAPPED +flag is ignored. .It Dv AI_CANONNAME If the .Dv AI_CANONNAME bit is set, a successful call to .Fn getaddrinfo will return a NUL-terminated string containing the canonical name of the specified hostname in the .Fa ai_canonname element of the first .Li addrinfo structure returned. .It Dv AI_NUMERICHOST If the .Dv AI_NUMERICHOST bit is set, it indicates that .Fa hostname should be treated as a numeric string defining an IPv4 or IPv6 address and no name resolution should be attempted. .It Dv AI_NUMERICSERV If the .Dv AI_NUMERICSERV bit is set, then a non-null .Fa servname string supplied shall be a numeric port string. Otherwise, an .Dv EAI_NONAME error shall be returned. This bit shall prevent any type of name resolution service (for example, NIS+) from being invoked. .It Dv AI_PASSIVE If the .Dv AI_PASSIVE bit is set it indicates that the returned socket address structure is intended for use in a call to .Xr bind 2 . In this case, if the .Fa hostname argument is the null pointer, then the IP address portion of the socket address structure will be set to .Dv INADDR_ANY for an IPv4 address or .Dv IN6ADDR_ANY_INIT for an IPv6 address. .Pp If the .Dv AI_PASSIVE bit is not set, the returned socket address structure will be ready for use in a call to .Xr connect 2 for a connection-oriented protocol or .Xr connect 2 , .Xr sendto 2 , or .Xr sendmsg 2 if a connectionless protocol was chosen. The .Tn IP address portion of the socket address structure will be set to the loopback address if .Fa hostname is the null pointer and .Dv AI_PASSIVE is not set. +.It Dv AI_V4MAPPED +If the +.Dv AI_V4MAPPED +flag is specified along with an ai_family of +.Dv AF_INET6 , +then +.Fn getaddrinfo +shall return IPv4-mapped IPv6 addresses on finding no matching IPv6 addresses ( +.Fa ai_addrlen +shall be 16). +.Pp +For example, when using the DNS, if no AAAA records are found then a query is made for A records and any found are returned as IPv4-mapped IPv6 addresses. +.Pp +The +.Dv AI_V4MAPPED +flag shall be ignored unless +.Fa ai_family +equals +.Dv AF_INET6 . .El .El .Pp All other elements of the .Li addrinfo structure passed via .Fa hints must be zero or the null pointer. .Pp If .Fa hints is the null pointer, .Fn getaddrinfo behaves as if the caller provided a .Li struct addrinfo with .Fa ai_family set to -.Dv PF_UNSPEC +.Dv AF_UNSPEC and all other elements set to zero or .Dv NULL . .Pp After a successful call to .Fn getaddrinfo , .Fa *res is a pointer to a linked list of one or more .Li addrinfo structures. The list can be traversed by following the .Fa ai_next pointer in each .Li addrinfo structure until a null pointer is encountered. Each returned .Li addrinfo structure contains three members that are suitable for a call to .Xr socket 2 : .Fa ai_family, .Fa ai_socktype, and .Fa ai_protocol . For each .Li addrinfo structure in the list, the .Fa ai_addr member points to a filled-in socket address structure of length .Fa ai_addrlen . .Pp This implementation of .Fn getaddrinfo allows numeric IPv6 address notation with scope identifier, as documented in chapter 11 of RFC 4007. By appending the percent character and scope identifier to addresses, one can fill the .Li sin6_scope_id field for addresses. This would make management of scoped addresses easier and allows cut-and-paste input of scoped addresses. .Pp At this moment the code supports only link-local addresses with the format. The scope identifier is hardcoded to the name of the hardware interface associated with the link .Po such as .Li ne0 .Pc . An example is .Dq Li fe80::1%ne0 , which means .Do .Li fe80::1 on the link associated with the .Li ne0 interface .Dc . .Pp The current implementation assumes a one-to-one relationship between the interface and link, which is not necessarily true from the specification. .Pp All of the information returned by .Fn getaddrinfo is dynamically allocated: the .Li addrinfo structures themselves as well as the socket address structures and the canonical host name strings included in the .Li addrinfo structures. .Pp Memory allocated for the dynamically allocated structures created by a successful call to .Fn getaddrinfo is released by the .Fn freeaddrinfo function. The .Fa ai pointer should be a .Li addrinfo structure created by a call to .Fn getaddrinfo . .Sh RETURN VALUES .Fn getaddrinfo returns zero on success or one of the error codes listed in .Xr gai_strerror 3 if an error occurs. .Sh EXAMPLES The following code tries to connect to .Dq Li www.kame.net service .Dq Li http via a stream socket. It loops through all the addresses available, regardless of address family. If the destination resolves to an IPv4 address, it will use an .Dv AF_INET socket. Similarly, if it resolves to IPv6, an .Dv AF_INET6 socket is used. Observe that there is no hardcoded reference to a particular address family. The code works even if .Fn getaddrinfo returns addresses that are not IPv4/v6. .Bd -literal -offset indent struct addrinfo hints, *res, *res0; int error; int s; const char *cause = NULL; memset(&hints, 0, sizeof(hints)); -hints.ai_family = PF_UNSPEC; +hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; error = getaddrinfo("www.kame.net", "http", &hints, &res0); if (error) { errx(1, "%s", gai_strerror(error)); /* NOTREACHED */ } s = -1; for (res = res0; res; res = res->ai_next) { s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if (s < 0) { cause = "socket"; continue; } if (connect(s, res->ai_addr, res->ai_addrlen) < 0) { cause = "connect"; close(s); s = -1; continue; } break; /* okay we got one */ } if (s < 0) { err(1, "%s", cause); /* NOTREACHED */ } freeaddrinfo(res0); .Ed .Pp The following example tries to open a wildcard listening socket onto service .Dq Li http , for all the address families available. .Bd -literal -offset indent struct addrinfo hints, *res, *res0; int error; int s[MAXSOCK]; int nsock; const char *cause = NULL; memset(&hints, 0, sizeof(hints)); -hints.ai_family = PF_UNSPEC; +hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; error = getaddrinfo(NULL, "http", &hints, &res0); if (error) { errx(1, "%s", gai_strerror(error)); /* NOTREACHED */ } nsock = 0; for (res = res0; res && nsock < MAXSOCK; res = res->ai_next) { s[nsock] = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if (s[nsock] < 0) { cause = "socket"; continue; } if (bind(s[nsock], res->ai_addr, res->ai_addrlen) < 0) { cause = "bind"; close(s[nsock]); continue; } (void) listen(s[nsock], 5); nsock++; } if (nsock == 0) { err(1, "%s", cause); /* NOTREACHED */ } freeaddrinfo(res0); .Ed .Sh SEE ALSO .Xr bind 2 , .Xr connect 2 , .Xr send 2 , .Xr socket 2 , .Xr gai_strerror 3 , .Xr gethostbyname 3 , .Xr getnameinfo 3 , .Xr getservbyname 3 , .Xr resolver 3 , .Xr hosts 5 , .Xr resolv.conf 5 , .Xr services 5 , .Xr hostname 7 , .Xr named 8 .Rs .%A R. Gilligan .%A S. Thomson .%A J. Bound .%A J. McCann .%A W. Stevens .%T Basic Socket Interface Extensions for IPv6 .%R RFC 3493 .%D February 2003 .Re .Rs .%A S. Deering .%A B. Haberman .%A T. Jinmei .%A E. Nordmark .%A B. Zill .%T "IPv6 Scoped Address Architecture" .%R RFC 4007 .%D March 2005 .Re .Rs .%A Craig Metz .%T Protocol Independence Using the Sockets API .%B "Proceedings of the freenix track: 2000 USENIX annual technical conference" .%D June 2000 .Re .Sh STANDARDS The .Fn getaddrinfo function is defined by the .St -p1003.1-2004 specification and documented in .Dv "RFC 3493" , .Dq Basic Socket Interface Extensions for IPv6 . Index: user/ngie/stable-10-libnv/lib/libc/net/getaddrinfo.c =================================================================== --- user/ngie/stable-10-libnv/lib/libc/net/getaddrinfo.c (revision 292856) +++ user/ngie/stable-10-libnv/lib/libc/net/getaddrinfo.c (revision 292857) @@ -1,2906 +1,3018 @@ /* $KAME: getaddrinfo.c,v 1.15 2000/07/09 04:37:24 itojun Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * "#ifdef FAITH" part is local hack for supporting IPv4-v6 translator. * * Issues to be discussed: * - Return values. There are nonstandard return values defined and used * in the source code. This is because RFC2553 is silent about which error * code must be returned for which situation. * - freeaddrinfo(NULL). RFC2553 is silent about it. XNET 5.2 says it is * invalid. current code - SEGV on freeaddrinfo(NULL) * * Note: * - The code filters out AFs that are not supported by the kernel, * when globbing NULL hostname (to loopback, or wildcard). Is it the right * thing to do? What is the relationship with post-RFC2553 AI_ADDRCONFIG * in ai_flags? * - (post-2553) semantics of AI_ADDRCONFIG itself is too vague. * (1) what should we do against numeric hostname (2) what should we do * against NULL hostname (3) what is AI_ADDRCONFIG itself. AF not ready? * non-loopback address configured? global address configured? * * OS specific notes for freebsd4: * - FreeBSD supported $GAI. The code does not. */ #include __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include #include #include #include #include #include #include #ifdef INET6 #include #include #include #include #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "res_config.h" #ifdef DEBUG #include #endif #include #include #include "un-namespace.h" +#include "netdb_private.h" #include "libc_private.h" #ifdef NS_CACHING #include "nscache.h" #endif #if defined(__KAME__) && defined(INET6) # define FAITH #endif #define ANY 0 #define YES 1 #define NO 0 static const char in_addrany[] = { 0, 0, 0, 0 }; static const char in_loopback[] = { 127, 0, 0, 1 }; #ifdef INET6 static const char in6_addrany[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; static const char in6_loopback[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; #endif struct policyqueue { TAILQ_ENTRY(policyqueue) pc_entry; #ifdef INET6 struct in6_addrpolicy pc_policy; #endif }; TAILQ_HEAD(policyhead, policyqueue); static const struct afd { int a_af; int a_addrlen; socklen_t a_socklen; int a_off; const char *a_addrany; const char *a_loopback; int a_scoped; } afdl [] = { #ifdef INET6 #define N_INET6 0 {PF_INET6, sizeof(struct in6_addr), sizeof(struct sockaddr_in6), offsetof(struct sockaddr_in6, sin6_addr), in6_addrany, in6_loopback, 1}, #define N_INET 1 #else #define N_INET 0 #endif {PF_INET, sizeof(struct in_addr), sizeof(struct sockaddr_in), offsetof(struct sockaddr_in, sin_addr), in_addrany, in_loopback, 0}, {0, 0, 0, 0, NULL, NULL, 0}, }; struct explore { int e_af; int e_socktype; int e_protocol; int e_wild; #define WILD_AF(ex) ((ex)->e_wild & 0x01) #define WILD_SOCKTYPE(ex) ((ex)->e_wild & 0x02) #define WILD_PROTOCOL(ex) ((ex)->e_wild & 0x04) }; static const struct explore explore[] = { #if 0 { PF_LOCAL, ANY, ANY, 0x01 }, #endif #ifdef INET6 { PF_INET6, SOCK_DGRAM, IPPROTO_UDP, 0x07 }, { PF_INET6, SOCK_STREAM, IPPROTO_TCP, 0x07 }, { PF_INET6, SOCK_STREAM, IPPROTO_SCTP, 0x03 }, { PF_INET6, SOCK_SEQPACKET, IPPROTO_SCTP, 0x07 }, { PF_INET6, SOCK_DGRAM, IPPROTO_UDPLITE, 0x03 }, { PF_INET6, SOCK_RAW, ANY, 0x05 }, #endif { PF_INET, SOCK_DGRAM, IPPROTO_UDP, 0x07 }, { PF_INET, SOCK_STREAM, IPPROTO_TCP, 0x07 }, { PF_INET, SOCK_STREAM, IPPROTO_SCTP, 0x03 }, { PF_INET, SOCK_SEQPACKET, IPPROTO_SCTP, 0x07 }, { PF_INET, SOCK_DGRAM, IPPROTO_UDPLITE, 0x03 }, { PF_INET, SOCK_RAW, ANY, 0x05 }, { -1, 0, 0, 0 }, }; #ifdef INET6 #define PTON_MAX 16 #else #define PTON_MAX 4 #endif #define AIO_SRCFLAG_DEPRECATED 0x1 struct ai_order { union { struct sockaddr_storage aiou_ss; struct sockaddr aiou_sa; } aio_src_un; #define aio_srcsa aio_src_un.aiou_sa u_int32_t aio_srcflag; int aio_srcscope; int aio_dstscope; struct policyqueue *aio_srcpolicy; struct policyqueue *aio_dstpolicy; struct addrinfo *aio_ai; int aio_matchlen; }; static const ns_src default_dns_files[] = { { NSSRC_FILES, NS_SUCCESS }, { NSSRC_DNS, NS_SUCCESS }, { 0 } }; struct res_target { struct res_target *next; const char *name; /* domain name */ int qclass, qtype; /* class and type of query */ u_char *answer; /* buffer to put answer */ int anslen; /* size of answer buffer */ int n; /* result length */ }; #define MAXPACKET (64*1024) typedef union { HEADER hdr; u_char buf[MAXPACKET]; } querybuf; static int str2number(const char *, int *); static int explore_copy(const struct addrinfo *, const struct addrinfo *, struct addrinfo **); static int explore_null(const struct addrinfo *, const char *, struct addrinfo **); static int explore_numeric(const struct addrinfo *, const char *, const char *, struct addrinfo **, const char *); static int explore_numeric_scope(const struct addrinfo *, const char *, const char *, struct addrinfo **); static int get_canonname(const struct addrinfo *, struct addrinfo *, const char *); static struct addrinfo *get_ai(const struct addrinfo *, const struct afd *, const char *); static struct addrinfo *copy_ai(const struct addrinfo *); static int get_portmatch(const struct addrinfo *, const char *); static int get_port(struct addrinfo *, const char *, int); static const struct afd *find_afd(int); static int addrconfig(struct addrinfo *); #ifdef INET6 static int is_ifdisabled(char *); #endif static void set_source(struct ai_order *, struct policyhead *); static int comp_dst(const void *, const void *); #ifdef INET6 static int ip6_str2scopeid(char *, struct sockaddr_in6 *, u_int32_t *); #endif static int gai_addr2scopetype(struct sockaddr *); static int explore_fqdn(const struct addrinfo *, const char *, const char *, struct addrinfo **); static int reorder(struct addrinfo *); static int get_addrselectpolicy(struct policyhead *); static void free_addrselectpolicy(struct policyhead *); static struct policyqueue *match_addrselectpolicy(struct sockaddr *, struct policyhead *); static int matchlen(struct sockaddr *, struct sockaddr *); static struct addrinfo *getanswer(const querybuf *, int, const char *, int, const struct addrinfo *, res_state); #if defined(RESOLVSORT) static int addr4sort(struct addrinfo *, res_state); #endif static int _dns_getaddrinfo(void *, void *, va_list); static void _sethtent(FILE **); static void _endhtent(FILE **); static struct addrinfo *_gethtent(FILE **, const char *, const struct addrinfo *); static int _files_getaddrinfo(void *, void *, va_list); #ifdef YP static struct addrinfo *_yphostent(char *, const struct addrinfo *); static int _yp_getaddrinfo(void *, void *, va_list); #endif #ifdef NS_CACHING static int addrinfo_id_func(char *, size_t *, va_list, void *); static int addrinfo_marshal_func(char *, size_t *, void *, va_list, void *); static int addrinfo_unmarshal_func(char *, size_t, void *, va_list, void *); #endif static int res_queryN(const char *, struct res_target *, res_state); static int res_searchN(const char *, struct res_target *, res_state); static int res_querydomainN(const char *, const char *, struct res_target *, res_state); /* XXX macros that make external reference is BAD. */ #define GET_AI(ai, afd, addr) \ do { \ /* external reference: pai, error, and label free */ \ (ai) = get_ai(pai, (afd), (addr)); \ if ((ai) == NULL) { \ error = EAI_MEMORY; \ goto free; \ } \ } while (/*CONSTCOND*/0) #define GET_PORT(ai, serv) \ do { \ /* external reference: error and label free */ \ error = get_port((ai), (serv), 0); \ if (error != 0) \ goto free; \ } while (/*CONSTCOND*/0) #define GET_CANONNAME(ai, str) \ do { \ /* external reference: pai, error and label free */ \ error = get_canonname(pai, (ai), (str)); \ if (error != 0) \ goto free; \ } while (/*CONSTCOND*/0) #define ERR(err) \ do { \ /* external reference: error, and label bad */ \ error = (err); \ goto bad; \ /*NOTREACHED*/ \ } while (/*CONSTCOND*/0) #define MATCH_FAMILY(x, y, w) \ ((x) == (y) || (/*CONSTCOND*/(w) && ((x) == PF_UNSPEC || (y) == PF_UNSPEC))) #define MATCH(x, y, w) \ ((x) == (y) || (/*CONSTCOND*/(w) && ((x) == ANY || (y) == ANY))) void freeaddrinfo(struct addrinfo *ai) { struct addrinfo *next; do { next = ai->ai_next; if (ai->ai_canonname) free(ai->ai_canonname); /* no need to free(ai->ai_addr) */ free(ai); ai = next; } while (ai); } static int str2number(const char *p, int *portp) { char *ep; unsigned long v; if (*p == '\0') return -1; ep = NULL; errno = 0; v = strtoul(p, &ep, 10); if (errno == 0 && ep && *ep == '\0' && v <= UINT_MAX) { *portp = v; return 0; } else return -1; } int getaddrinfo(const char *hostname, const char *servname, const struct addrinfo *hints, struct addrinfo **res) { struct addrinfo sentinel; struct addrinfo *cur; int error = 0; struct addrinfo ai, ai0, *afai; struct addrinfo *pai; const struct afd *afd; const struct explore *ex; struct addrinfo *afailist[sizeof(afdl)/sizeof(afdl[0])]; struct addrinfo *afai_unspec; int found; int numeric = 0; /* ensure we return NULL on errors */ *res = NULL; memset(&ai, 0, sizeof(ai)); memset(afailist, 0, sizeof(afailist)); afai_unspec = NULL; memset(&sentinel, 0, sizeof(sentinel)); cur = &sentinel; pai = &ai; pai->ai_flags = 0; pai->ai_family = PF_UNSPEC; pai->ai_socktype = ANY; pai->ai_protocol = ANY; pai->ai_addrlen = 0; pai->ai_canonname = NULL; pai->ai_addr = NULL; pai->ai_next = NULL; if (hostname == NULL && servname == NULL) return EAI_NONAME; if (hints) { /* error check for hints */ if (hints->ai_addrlen || hints->ai_canonname || hints->ai_addr || hints->ai_next) ERR(EAI_BADHINTS); /* xxx */ if (hints->ai_flags & ~AI_MASK) ERR(EAI_BADFLAGS); switch (hints->ai_family) { case PF_UNSPEC: case PF_INET: #ifdef INET6 case PF_INET6: #endif break; default: ERR(EAI_FAMILY); } memcpy(pai, hints, sizeof(*pai)); /* * if both socktype/protocol are specified, check if they * are meaningful combination. */ if (pai->ai_socktype != ANY && pai->ai_protocol != ANY) { for (ex = explore; ex->e_af >= 0; ex++) { if (!MATCH_FAMILY(pai->ai_family, ex->e_af, WILD_AF(ex))) continue; if (!MATCH(pai->ai_socktype, ex->e_socktype, WILD_SOCKTYPE(ex))) continue; if (!MATCH(pai->ai_protocol, ex->e_protocol, WILD_PROTOCOL(ex))) continue; /* matched */ break; } if (ex->e_af < 0) ERR(EAI_BADHINTS); } } /* + * RFC 3493: AI_ALL and AI_V4MAPPED are effective only against + * AF_INET6 query. They need to be ignored if specified in other + * occassions. + */ + switch (pai->ai_flags & (AI_ALL | AI_V4MAPPED)) { + case AI_V4MAPPED: + case AI_ALL | AI_V4MAPPED: +#ifdef INET6 + if (pai->ai_family != AF_INET6) + pai->ai_flags &= ~(AI_ALL | AI_V4MAPPED); + break; +#endif + case AI_ALL: + pai->ai_flags &= ~(AI_ALL | AI_V4MAPPED); + break; + } + + /* * check for special cases. (1) numeric servname is disallowed if * socktype/protocol are left unspecified. (2) servname is disallowed * for raw and other inet{,6} sockets. */ if (MATCH_FAMILY(pai->ai_family, PF_INET, 1) #ifdef PF_INET6 || MATCH_FAMILY(pai->ai_family, PF_INET6, 1) #endif ) { ai0 = *pai; /* backup *pai */ if (pai->ai_family == PF_UNSPEC) { #ifdef PF_INET6 pai->ai_family = PF_INET6; #else pai->ai_family = PF_INET; #endif } error = get_portmatch(pai, servname); if (error) goto bad; *pai = ai0; } ai0 = *pai; /* * NULL hostname, or numeric hostname. * If numeric representation of AF1 can be interpreted as FQDN * representation of AF2, we need to think again about the code below. */ found = 0; for (afd = afdl; afd->a_af; afd++) { *pai = ai0; if (!MATCH_FAMILY(pai->ai_family, afd->a_af, 1)) continue; if (pai->ai_family == PF_UNSPEC) pai->ai_family = afd->a_af; if (hostname == NULL) { error = explore_null(pai, servname, &afailist[afd - afdl]); /* * Errors from explore_null should be unexpected and * be caught to avoid returning an incomplete result. */ if (error != 0) goto bad; } else { error = explore_numeric_scope(pai, hostname, servname, &afailist[afd - afdl]); /* * explore_numeric_scope returns an error for address * families that do not match that of hostname. * Thus we should not catch the error at this moment. */ } if (!error && afailist[afd - afdl]) found++; } if (found) { numeric = 1; goto globcopy; } if (hostname == NULL) ERR(EAI_NONAME); /* used to be EAI_NODATA */ if (pai->ai_flags & AI_NUMERICHOST) ERR(EAI_NONAME); if ((pai->ai_flags & AI_ADDRCONFIG) != 0 && !addrconfig(&ai0)) ERR(EAI_FAIL); /* * hostname as alphabetical name. */ *pai = ai0; error = explore_fqdn(pai, hostname, servname, &afai_unspec); globcopy: for (ex = explore; ex->e_af >= 0; ex++) { *pai = ai0; if (!MATCH_FAMILY(pai->ai_family, ex->e_af, WILD_AF(ex))) continue; if (!MATCH(pai->ai_socktype, ex->e_socktype, WILD_SOCKTYPE(ex))) continue; if (!MATCH(pai->ai_protocol, ex->e_protocol, WILD_PROTOCOL(ex))) continue; if (pai->ai_family == PF_UNSPEC) pai->ai_family = ex->e_af; if (pai->ai_socktype == ANY && ex->e_socktype != ANY) pai->ai_socktype = ex->e_socktype; if (pai->ai_protocol == ANY && ex->e_protocol != ANY) pai->ai_protocol = ex->e_protocol; /* * if the servname does not match socktype/protocol, ignore it. */ if (get_portmatch(pai, servname) != 0) continue; if (afai_unspec) afai = afai_unspec; else { if ((afd = find_afd(pai->ai_family)) == NULL) continue; /* XXX assumes that afd points inside afdl[] */ afai = afailist[afd - afdl]; } if (!afai) continue; error = explore_copy(pai, afai, &cur->ai_next); if (error != 0) goto bad; while (cur && cur->ai_next) cur = cur->ai_next; } /* * ensure we return either: * - error == 0, non-NULL *res * - error != 0, NULL *res */ if (error == 0) { if (sentinel.ai_next) { /* * If the returned entry is for an active connection, * and the given name is not numeric, reorder the * list, so that the application would try the list * in the most efficient order. Since the head entry * of the original list may contain ai_canonname and * that entry may be moved elsewhere in the new list, * we keep the pointer and will restore it in the new * head entry. (Note that RFC3493 requires the head * entry store it when requested by the caller). */ if (hints == NULL || !(hints->ai_flags & AI_PASSIVE)) { if (!numeric) { char *canonname; canonname = sentinel.ai_next->ai_canonname; sentinel.ai_next->ai_canonname = NULL; (void)reorder(&sentinel); if (sentinel.ai_next->ai_canonname == NULL) { sentinel.ai_next->ai_canonname = canonname; } else if (canonname != NULL) free(canonname); } } *res = sentinel.ai_next; } else error = EAI_FAIL; } bad: if (afai_unspec) freeaddrinfo(afai_unspec); for (afd = afdl; afd->a_af; afd++) { if (afailist[afd - afdl]) freeaddrinfo(afailist[afd - afdl]); } if (!*res) if (sentinel.ai_next) freeaddrinfo(sentinel.ai_next); return (error); } static int reorder(struct addrinfo *sentinel) { struct addrinfo *ai, **aip; struct ai_order *aio; int i, n; struct policyhead policyhead; /* count the number of addrinfo elements for sorting. */ for (n = 0, ai = sentinel->ai_next; ai != NULL; ai = ai->ai_next, n++) ; /* * If the number is small enough, we can skip the reordering process. */ if (n <= 1) return(n); /* allocate a temporary array for sort and initialization of it. */ if ((aio = malloc(sizeof(*aio) * n)) == NULL) return(n); /* give up reordering */ memset(aio, 0, sizeof(*aio) * n); /* retrieve address selection policy from the kernel */ TAILQ_INIT(&policyhead); if (!get_addrselectpolicy(&policyhead)) { /* no policy is installed into kernel, we don't sort. */ free(aio); return (n); } for (i = 0, ai = sentinel->ai_next; i < n; ai = ai->ai_next, i++) { aio[i].aio_ai = ai; aio[i].aio_dstscope = gai_addr2scopetype(ai->ai_addr); aio[i].aio_dstpolicy = match_addrselectpolicy(ai->ai_addr, &policyhead); set_source(&aio[i], &policyhead); } /* perform sorting. */ qsort(aio, n, sizeof(*aio), comp_dst); /* reorder the addrinfo chain. */ for (i = 0, aip = &sentinel->ai_next; i < n; i++) { *aip = aio[i].aio_ai; aip = &aio[i].aio_ai->ai_next; } *aip = NULL; /* cleanup and return */ free(aio); free_addrselectpolicy(&policyhead); return(n); } static int get_addrselectpolicy(struct policyhead *head) { #ifdef INET6 int mib[] = { CTL_NET, PF_INET6, IPPROTO_IPV6, IPV6CTL_ADDRCTLPOLICY }; size_t l; char *buf; struct in6_addrpolicy *pol, *ep; if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), NULL, &l, NULL, 0) < 0) return (0); if (l == 0) return (0); if ((buf = malloc(l)) == NULL) return (0); if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), buf, &l, NULL, 0) < 0) { free(buf); return (0); } ep = (struct in6_addrpolicy *)(buf + l); for (pol = (struct in6_addrpolicy *)buf; pol + 1 <= ep; pol++) { struct policyqueue *new; if ((new = malloc(sizeof(*new))) == NULL) { free_addrselectpolicy(head); /* make the list empty */ break; } new->pc_policy = *pol; TAILQ_INSERT_TAIL(head, new, pc_entry); } free(buf); return (1); #else return (0); #endif } static void free_addrselectpolicy(struct policyhead *head) { struct policyqueue *ent, *nent; for (ent = TAILQ_FIRST(head); ent; ent = nent) { nent = TAILQ_NEXT(ent, pc_entry); TAILQ_REMOVE(head, ent, pc_entry); free(ent); } } static struct policyqueue * match_addrselectpolicy(struct sockaddr *addr, struct policyhead *head) { #ifdef INET6 struct policyqueue *ent, *bestent = NULL; struct in6_addrpolicy *pol; int matchlen, bestmatchlen = -1; u_char *mp, *ep, *k, *p, m; struct sockaddr_in6 key; switch(addr->sa_family) { case AF_INET6: key = *(struct sockaddr_in6 *)addr; break; case AF_INET: /* convert the address into IPv4-mapped IPv6 address. */ memset(&key, 0, sizeof(key)); key.sin6_family = AF_INET6; key.sin6_len = sizeof(key); - key.sin6_addr.s6_addr[10] = 0xff; - key.sin6_addr.s6_addr[11] = 0xff; - memcpy(&key.sin6_addr.s6_addr[12], - &((struct sockaddr_in *)addr)->sin_addr, 4); + _map_v4v6_address( + (char *)&((struct sockaddr_in *)addr)->sin_addr, + (char *)&key.sin6_addr); break; default: return(NULL); } for (ent = TAILQ_FIRST(head); ent; ent = TAILQ_NEXT(ent, pc_entry)) { pol = &ent->pc_policy; matchlen = 0; mp = (u_char *)&pol->addrmask.sin6_addr; ep = mp + 16; /* XXX: scope field? */ k = (u_char *)&key.sin6_addr; p = (u_char *)&pol->addr.sin6_addr; for (; mp < ep && *mp; mp++, k++, p++) { m = *mp; if ((*k & m) != *p) goto next; /* not match */ if (m == 0xff) /* short cut for a typical case */ matchlen += 8; else { while (m >= 0x80) { matchlen++; m <<= 1; } } } /* matched. check if this is better than the current best. */ if (matchlen > bestmatchlen) { bestent = ent; bestmatchlen = matchlen; } next: continue; } return(bestent); #else return(NULL); #endif } static void set_source(struct ai_order *aio, struct policyhead *ph) { struct addrinfo ai = *aio->aio_ai; struct sockaddr_storage ss; socklen_t srclen; int s; /* set unspec ("no source is available"), just in case */ aio->aio_srcsa.sa_family = AF_UNSPEC; aio->aio_srcscope = -1; switch(ai.ai_family) { case AF_INET: #ifdef INET6 case AF_INET6: #endif break; default: /* ignore unsupported AFs explicitly */ return; } /* XXX: make a dummy addrinfo to call connect() */ ai.ai_socktype = SOCK_DGRAM; ai.ai_protocol = IPPROTO_UDP; /* is UDP too specific? */ ai.ai_next = NULL; memset(&ss, 0, sizeof(ss)); memcpy(&ss, ai.ai_addr, ai.ai_addrlen); ai.ai_addr = (struct sockaddr *)&ss; get_port(&ai, "1", 0); /* open a socket to get the source address for the given dst */ if ((s = _socket(ai.ai_family, ai.ai_socktype | SOCK_CLOEXEC, ai.ai_protocol)) < 0) return; /* give up */ +#ifdef INET6 + if (ai.ai_family == AF_INET6) { + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)ai.ai_addr; + int off = 0; + + if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) + (void)_setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, + (char *)&off, sizeof(off)); + } +#endif if (_connect(s, ai.ai_addr, ai.ai_addrlen) < 0) goto cleanup; srclen = ai.ai_addrlen; if (_getsockname(s, &aio->aio_srcsa, &srclen) < 0) { aio->aio_srcsa.sa_family = AF_UNSPEC; goto cleanup; } aio->aio_srcscope = gai_addr2scopetype(&aio->aio_srcsa); aio->aio_srcpolicy = match_addrselectpolicy(&aio->aio_srcsa, ph); aio->aio_matchlen = matchlen(&aio->aio_srcsa, aio->aio_ai->ai_addr); #ifdef INET6 if (ai.ai_family == AF_INET6) { struct in6_ifreq ifr6; u_int32_t flags6; memset(&ifr6, 0, sizeof(ifr6)); memcpy(&ifr6.ifr_addr, ai.ai_addr, ai.ai_addrlen); if (_ioctl(s, SIOCGIFAFLAG_IN6, &ifr6) == 0) { flags6 = ifr6.ifr_ifru.ifru_flags6; if ((flags6 & IN6_IFF_DEPRECATED)) aio->aio_srcflag |= AIO_SRCFLAG_DEPRECATED; } } #endif cleanup: _close(s); return; } static int matchlen(struct sockaddr *src, struct sockaddr *dst) { int match = 0; u_char *s, *d; u_char *lim, r; int addrlen; switch (src->sa_family) { #ifdef INET6 case AF_INET6: s = (u_char *)&((struct sockaddr_in6 *)src)->sin6_addr; d = (u_char *)&((struct sockaddr_in6 *)dst)->sin6_addr; addrlen = sizeof(struct in6_addr); lim = s + addrlen; break; #endif case AF_INET: s = (u_char *)&((struct sockaddr_in *)src)->sin_addr; d = (u_char *)&((struct sockaddr_in *)dst)->sin_addr; addrlen = sizeof(struct in_addr); lim = s + addrlen; break; default: return(0); } while (s < lim) if ((r = (*d++ ^ *s++)) != 0) { while (r < addrlen * 8) { match++; r <<= 1; } break; } else match += 8; return(match); } static int comp_dst(const void *arg1, const void *arg2) { const struct ai_order *dst1 = arg1, *dst2 = arg2; /* * Rule 1: Avoid unusable destinations. * XXX: we currently do not consider if an appropriate route exists. */ if (dst1->aio_srcsa.sa_family != AF_UNSPEC && dst2->aio_srcsa.sa_family == AF_UNSPEC) { return(-1); } if (dst1->aio_srcsa.sa_family == AF_UNSPEC && dst2->aio_srcsa.sa_family != AF_UNSPEC) { return(1); } /* Rule 2: Prefer matching scope. */ if (dst1->aio_dstscope == dst1->aio_srcscope && dst2->aio_dstscope != dst2->aio_srcscope) { return(-1); } if (dst1->aio_dstscope != dst1->aio_srcscope && dst2->aio_dstscope == dst2->aio_srcscope) { return(1); } /* Rule 3: Avoid deprecated addresses. */ if (dst1->aio_srcsa.sa_family != AF_UNSPEC && dst2->aio_srcsa.sa_family != AF_UNSPEC) { if (!(dst1->aio_srcflag & AIO_SRCFLAG_DEPRECATED) && (dst2->aio_srcflag & AIO_SRCFLAG_DEPRECATED)) { return(-1); } if ((dst1->aio_srcflag & AIO_SRCFLAG_DEPRECATED) && !(dst2->aio_srcflag & AIO_SRCFLAG_DEPRECATED)) { return(1); } } /* Rule 4: Prefer home addresses. */ /* XXX: not implemented yet */ /* Rule 5: Prefer matching label. */ #ifdef INET6 if (dst1->aio_srcpolicy && dst1->aio_dstpolicy && dst1->aio_srcpolicy->pc_policy.label == dst1->aio_dstpolicy->pc_policy.label && (dst2->aio_srcpolicy == NULL || dst2->aio_dstpolicy == NULL || dst2->aio_srcpolicy->pc_policy.label != dst2->aio_dstpolicy->pc_policy.label)) { return(-1); } if (dst2->aio_srcpolicy && dst2->aio_dstpolicy && dst2->aio_srcpolicy->pc_policy.label == dst2->aio_dstpolicy->pc_policy.label && (dst1->aio_srcpolicy == NULL || dst1->aio_dstpolicy == NULL || dst1->aio_srcpolicy->pc_policy.label != dst1->aio_dstpolicy->pc_policy.label)) { return(1); } #endif /* Rule 6: Prefer higher precedence. */ #ifdef INET6 if (dst1->aio_dstpolicy && (dst2->aio_dstpolicy == NULL || dst1->aio_dstpolicy->pc_policy.preced > dst2->aio_dstpolicy->pc_policy.preced)) { return(-1); } if (dst2->aio_dstpolicy && (dst1->aio_dstpolicy == NULL || dst2->aio_dstpolicy->pc_policy.preced > dst1->aio_dstpolicy->pc_policy.preced)) { return(1); } #endif /* Rule 7: Prefer native transport. */ /* XXX: not implemented yet */ /* Rule 8: Prefer smaller scope. */ if (dst1->aio_dstscope >= 0 && dst1->aio_dstscope < dst2->aio_dstscope) { return(-1); } if (dst2->aio_dstscope >= 0 && dst2->aio_dstscope < dst1->aio_dstscope) { return(1); } /* * Rule 9: Use longest matching prefix. * We compare the match length in a same AF only. */ if (dst1->aio_ai->ai_addr->sa_family == dst2->aio_ai->ai_addr->sa_family && dst1->aio_ai->ai_addr->sa_family != AF_INET) { if (dst1->aio_matchlen > dst2->aio_matchlen) { return(-1); } if (dst1->aio_matchlen < dst2->aio_matchlen) { return(1); } } /* Rule 10: Otherwise, leave the order unchanged. */ return(-1); } /* * Copy from scope.c. * XXX: we should standardize the functions and link them as standard * library. */ static int gai_addr2scopetype(struct sockaddr *sa) { #ifdef INET6 struct sockaddr_in6 *sa6; #endif struct sockaddr_in *sa4; switch(sa->sa_family) { #ifdef INET6 case AF_INET6: sa6 = (struct sockaddr_in6 *)sa; if (IN6_IS_ADDR_MULTICAST(&sa6->sin6_addr)) { /* just use the scope field of the multicast address */ return(sa6->sin6_addr.s6_addr[2] & 0x0f); } /* * Unicast addresses: map scope type to corresponding scope * value defined for multcast addresses. * XXX: hardcoded scope type values are bad... */ if (IN6_IS_ADDR_LOOPBACK(&sa6->sin6_addr)) return(1); /* node local scope */ if (IN6_IS_ADDR_LINKLOCAL(&sa6->sin6_addr)) return(2); /* link-local scope */ if (IN6_IS_ADDR_SITELOCAL(&sa6->sin6_addr)) return(5); /* site-local scope */ return(14); /* global scope */ break; #endif case AF_INET: /* * IPv4 pseudo scoping according to RFC 3484. */ sa4 = (struct sockaddr_in *)sa; /* IPv4 autoconfiguration addresses have link-local scope. */ if (((u_char *)&sa4->sin_addr)[0] == 169 && ((u_char *)&sa4->sin_addr)[1] == 254) return(2); /* Private addresses have site-local scope. */ if (((u_char *)&sa4->sin_addr)[0] == 10 || (((u_char *)&sa4->sin_addr)[0] == 172 && (((u_char *)&sa4->sin_addr)[1] & 0xf0) == 16) || (((u_char *)&sa4->sin_addr)[0] == 192 && ((u_char *)&sa4->sin_addr)[1] == 168)) return(14); /* XXX: It should be 5 unless NAT */ /* Loopback addresses have link-local scope. */ if (((u_char *)&sa4->sin_addr)[0] == 127) return(2); return(14); break; default: errno = EAFNOSUPPORT; /* is this a good error? */ return(-1); } } static int explore_copy(const struct addrinfo *pai, const struct addrinfo *src0, struct addrinfo **res) { int error; struct addrinfo sentinel, *cur; const struct addrinfo *src; error = 0; sentinel.ai_next = NULL; cur = &sentinel; for (src = src0; src != NULL; src = src->ai_next) { if (src->ai_family != pai->ai_family) continue; cur->ai_next = copy_ai(src); if (!cur->ai_next) { error = EAI_MEMORY; goto fail; } cur->ai_next->ai_socktype = pai->ai_socktype; cur->ai_next->ai_protocol = pai->ai_protocol; cur = cur->ai_next; } *res = sentinel.ai_next; return 0; fail: freeaddrinfo(sentinel.ai_next); return error; } /* * hostname == NULL. * passive socket -> anyaddr (0.0.0.0 or ::) * non-passive socket -> localhost (127.0.0.1 or ::1) */ static int explore_null(const struct addrinfo *pai, const char *servname, struct addrinfo **res) { int s; const struct afd *afd; struct addrinfo *ai; int error; *res = NULL; ai = NULL; /* * filter out AFs that are not supported by the kernel * XXX errno? */ s = _socket(pai->ai_family, SOCK_DGRAM | SOCK_CLOEXEC, 0); if (s < 0) { if (errno != EMFILE) return 0; } else _close(s); afd = find_afd(pai->ai_family); if (afd == NULL) return 0; if (pai->ai_flags & AI_PASSIVE) { GET_AI(ai, afd, afd->a_addrany); GET_PORT(ai, servname); } else { GET_AI(ai, afd, afd->a_loopback); GET_PORT(ai, servname); } *res = ai; return 0; free: if (ai != NULL) freeaddrinfo(ai); return error; } /* * numeric hostname */ static int explore_numeric(const struct addrinfo *pai, const char *hostname, const char *servname, struct addrinfo **res, const char *canonname) { const struct afd *afd; - struct addrinfo *ai; + struct addrinfo *ai, ai0; int error; char pton[PTON_MAX]; *res = NULL; ai = NULL; afd = find_afd(pai->ai_family); if (afd == NULL) return 0; switch (afd->a_af) { case AF_INET: /* * RFC3493 requires getaddrinfo() to accept AF_INET formats * that are accepted by inet_addr() and its family. The * accepted forms includes the "classful" one, which inet_pton * does not accept. So we need to separate the case for * AF_INET. */ if (inet_aton(hostname, (struct in_addr *)pton) != 1) return 0; break; default: - if (inet_pton(afd->a_af, hostname, pton) != 1) - return 0; + if (inet_pton(afd->a_af, hostname, pton) != 1) { + if (pai->ai_family != AF_INET6 || + (pai->ai_flags & AI_V4MAPPED) != AI_V4MAPPED) + return 0; + if (inet_aton(hostname, (struct in_addr *)pton) != 1) + return 0; + afd = &afdl[N_INET]; + ai0 = *pai; + ai0.ai_family = AF_INET; + pai = &ai0; + } break; } if (pai->ai_family == afd->a_af) { GET_AI(ai, afd, pton); GET_PORT(ai, servname); if ((pai->ai_flags & AI_CANONNAME)) { /* * Set the numeric address itself as the canonical * name, based on a clarification in RFC3493. */ GET_CANONNAME(ai, canonname); } } else { /* * XXX: This should not happen since we already matched the AF * by find_afd. */ ERR(EAI_FAMILY); } *res = ai; return 0; free: bad: if (ai != NULL) freeaddrinfo(ai); return error; } /* * numeric hostname with scope */ static int explore_numeric_scope(const struct addrinfo *pai, const char *hostname, const char *servname, struct addrinfo **res) { #if !defined(SCOPE_DELIMITER) || !defined(INET6) return explore_numeric(pai, hostname, servname, res, hostname); #else const struct afd *afd; struct addrinfo *cur; int error; char *cp, *hostname2 = NULL, *scope, *addr; struct sockaddr_in6 *sin6; afd = find_afd(pai->ai_family); if (afd == NULL) return 0; if (!afd->a_scoped) return explore_numeric(pai, hostname, servname, res, hostname); cp = strchr(hostname, SCOPE_DELIMITER); if (cp == NULL) return explore_numeric(pai, hostname, servname, res, hostname); /* * Handle special case of */ hostname2 = strdup(hostname); if (hostname2 == NULL) return EAI_MEMORY; /* terminate at the delimiter */ hostname2[cp - hostname] = '\0'; addr = hostname2; scope = cp + 1; error = explore_numeric(pai, addr, servname, res, hostname); if (error == 0) { u_int32_t scopeid; for (cur = *res; cur; cur = cur->ai_next) { if (cur->ai_family != AF_INET6) continue; sin6 = (struct sockaddr_in6 *)(void *)cur->ai_addr; if (ip6_str2scopeid(scope, sin6, &scopeid) == -1) { free(hostname2); freeaddrinfo(*res); *res = NULL; return(EAI_NONAME); /* XXX: is return OK? */ } sin6->sin6_scope_id = scopeid; } } free(hostname2); if (error && *res) { freeaddrinfo(*res); *res = NULL; } return error; #endif } static int get_canonname(const struct addrinfo *pai, struct addrinfo *ai, const char *str) { if ((pai->ai_flags & AI_CANONNAME) != 0) { ai->ai_canonname = strdup(str); if (ai->ai_canonname == NULL) return EAI_MEMORY; } return 0; } static struct addrinfo * get_ai(const struct addrinfo *pai, const struct afd *afd, const char *addr) { char *p; struct addrinfo *ai; #ifdef FAITH struct in6_addr faith_prefix; char *fp_str; int translate = 0; #endif +#ifdef INET6 + struct in6_addr mapaddr; +#endif #ifdef FAITH /* * Transfrom an IPv4 addr into a special IPv6 addr format for * IPv6->IPv4 translation gateway. (only TCP is supported now) * * +-----------------------------------+------------+ * | faith prefix part (12 bytes) | embedded | * | | IPv4 addr part (4 bytes) * +-----------------------------------+------------+ * * faith prefix part is specified as ascii IPv6 addr format * in environmental variable GAI. * For FAITH to work correctly, routing to faith prefix must be * setup toward a machine where a FAITH daemon operates. * Also, the machine must enable some mechanizm * (e.g. faith interface hack) to divert those packet with * faith prefixed destination addr to user-land FAITH daemon. */ fp_str = getenv("GAI"); if (fp_str && inet_pton(AF_INET6, fp_str, &faith_prefix) == 1 && afd->a_af == AF_INET && pai->ai_socktype == SOCK_STREAM) { u_int32_t v4a; u_int8_t v4a_top; memcpy(&v4a, addr, sizeof v4a); v4a_top = v4a >> IN_CLASSA_NSHIFT; if (!IN_MULTICAST(v4a) && !IN_EXPERIMENTAL(v4a) && v4a_top != 0 && v4a != IN_LOOPBACKNET) { afd = &afdl[N_INET6]; memcpy(&faith_prefix.s6_addr[12], addr, sizeof(struct in_addr)); translate = 1; } } #endif +#ifdef INET6 + if (afd->a_af == AF_INET && (pai->ai_flags & AI_V4MAPPED) != 0) { + afd = &afdl[N_INET6]; + _map_v4v6_address(addr, (char *)&mapaddr); + addr = (char *)&mapaddr; + } +#endif + ai = (struct addrinfo *)malloc(sizeof(struct addrinfo) + (afd->a_socklen)); if (ai == NULL) return NULL; memcpy(ai, pai, sizeof(struct addrinfo)); ai->ai_addr = (struct sockaddr *)(void *)(ai + 1); memset(ai->ai_addr, 0, (size_t)afd->a_socklen); ai->ai_addr->sa_len = afd->a_socklen; ai->ai_addrlen = afd->a_socklen; ai->ai_addr->sa_family = ai->ai_family = afd->a_af; p = (char *)(void *)(ai->ai_addr); #ifdef FAITH if (translate == 1) memcpy(p + afd->a_off, &faith_prefix, (size_t)afd->a_addrlen); else #endif memcpy(p + afd->a_off, addr, (size_t)afd->a_addrlen); return ai; } /* XXX need to malloc() the same way we do from other functions! */ static struct addrinfo * copy_ai(const struct addrinfo *pai) { struct addrinfo *ai; size_t l; l = sizeof(*ai) + pai->ai_addrlen; if ((ai = (struct addrinfo *)malloc(l)) == NULL) return NULL; memset(ai, 0, l); memcpy(ai, pai, sizeof(*ai)); ai->ai_addr = (struct sockaddr *)(void *)(ai + 1); memcpy(ai->ai_addr, pai->ai_addr, pai->ai_addrlen); if (pai->ai_canonname) { l = strlen(pai->ai_canonname) + 1; if ((ai->ai_canonname = malloc(l)) == NULL) { free(ai); return NULL; } strlcpy(ai->ai_canonname, pai->ai_canonname, l); } else { /* just to make sure */ ai->ai_canonname = NULL; } ai->ai_next = NULL; return ai; } static int get_portmatch(const struct addrinfo *ai, const char *servname) { /* get_port does not touch first argument when matchonly == 1. */ /* LINTED const cast */ return get_port((struct addrinfo *)ai, servname, 1); } static int get_port(struct addrinfo *ai, const char *servname, int matchonly) { const char *proto; struct servent *sp; int port, error; int allownumeric; if (servname == NULL) return 0; switch (ai->ai_family) { case AF_INET: #ifdef AF_INET6 case AF_INET6: #endif break; default: return 0; } switch (ai->ai_socktype) { case SOCK_RAW: return EAI_SERVICE; case SOCK_DGRAM: case SOCK_STREAM: case SOCK_SEQPACKET: allownumeric = 1; break; case ANY: switch (ai->ai_family) { case AF_INET: #ifdef AF_INET6 case AF_INET6: #endif allownumeric = 1; break; default: allownumeric = 0; break; } break; default: return EAI_SOCKTYPE; } error = str2number(servname, &port); if (error == 0) { if (!allownumeric) return EAI_SERVICE; if (port < 0 || port > 65535) return EAI_SERVICE; port = htons(port); } else { if (ai->ai_flags & AI_NUMERICSERV) return EAI_NONAME; switch (ai->ai_protocol) { case IPPROTO_UDP: proto = "udp"; break; case IPPROTO_TCP: proto = "tcp"; break; case IPPROTO_SCTP: proto = "sctp"; break; case IPPROTO_UDPLITE: proto = "udplite"; break; default: proto = NULL; break; } if ((sp = getservbyname(servname, proto)) == NULL) return EAI_SERVICE; port = sp->s_port; } if (!matchonly) { switch (ai->ai_family) { case AF_INET: ((struct sockaddr_in *)(void *) ai->ai_addr)->sin_port = port; break; #ifdef INET6 case AF_INET6: ((struct sockaddr_in6 *)(void *) ai->ai_addr)->sin6_port = port; break; #endif } } return 0; } static const struct afd * find_afd(int af) { const struct afd *afd; if (af == PF_UNSPEC) return NULL; for (afd = afdl; afd->a_af; afd++) { if (afd->a_af == af) return afd; } return NULL; } /* * RFC 3493: AI_ADDRCONFIG check. Determines which address families are * configured on the local system and correlates with pai->ai_family value. * If an address family is not configured on the system, it will not be * queried for. For this purpose, loopback addresses are not considered * configured addresses. * * XXX PF_UNSPEC -> PF_INET6 + PF_INET mapping needs to be in sync with * _dns_getaddrinfo. */ static int addrconfig(struct addrinfo *pai) { struct ifaddrs *ifaddrs, *ifa; struct sockaddr_in *sin; #ifdef INET6 struct sockaddr_in6 *sin6; #endif int seen_inet = 0, seen_inet6 = 0; if (getifaddrs(&ifaddrs) != 0) return (0); for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) { if (ifa->ifa_addr == NULL || (ifa->ifa_flags & IFF_UP) == 0) continue; switch (ifa->ifa_addr->sa_family) { case AF_INET: if (seen_inet) continue; sin = (struct sockaddr_in *)(ifa->ifa_addr); if (htonl(sin->sin_addr.s_addr) == INADDR_LOOPBACK) continue; seen_inet = 1; break; #ifdef INET6 case AF_INET6: if (seen_inet6) continue; sin6 = (struct sockaddr_in6 *)(ifa->ifa_addr); if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr)) continue; if ((ifa->ifa_flags & IFT_LOOP) != 0 && IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) continue; if (is_ifdisabled(ifa->ifa_name)) continue; seen_inet6 = 1; break; #endif } } freeifaddrs(ifaddrs); switch(pai->ai_family) { case AF_INET6: return (seen_inet6); case AF_INET: return (seen_inet); case AF_UNSPEC: if (seen_inet == seen_inet6) return (seen_inet); pai->ai_family = seen_inet ? AF_INET : AF_INET6; return (1); } return (1); } #ifdef INET6 static int is_ifdisabled(char *name) { struct in6_ndireq nd; int fd; if ((fd = _socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0)) < 0) return (-1); memset(&nd, 0, sizeof(nd)); strlcpy(nd.ifname, name, sizeof(nd.ifname)); if (_ioctl(fd, SIOCGIFINFO_IN6, &nd) < 0) { _close(fd); return (-1); } _close(fd); return ((nd.ndi.flags & ND6_IFF_IFDISABLED) != 0); } /* convert a string to a scope identifier. XXX: IPv6 specific */ static int ip6_str2scopeid(char *scope, struct sockaddr_in6 *sin6, u_int32_t *scopeid) { u_long lscopeid; struct in6_addr *a6; char *ep; a6 = &sin6->sin6_addr; /* empty scopeid portion is invalid */ if (*scope == '\0') return -1; if (IN6_IS_ADDR_LINKLOCAL(a6) || IN6_IS_ADDR_MC_LINKLOCAL(a6) || IN6_IS_ADDR_MC_NODELOCAL(a6)) { /* * We currently assume a one-to-one mapping between links * and interfaces, so we simply use interface indices for * like-local scopes. */ *scopeid = if_nametoindex(scope); if (*scopeid == 0) goto trynumeric; return 0; } /* still unclear about literal, allow numeric only - placeholder */ if (IN6_IS_ADDR_SITELOCAL(a6) || IN6_IS_ADDR_MC_SITELOCAL(a6)) goto trynumeric; if (IN6_IS_ADDR_MC_ORGLOCAL(a6)) goto trynumeric; else goto trynumeric; /* global */ /* try to convert to a numeric id as a last resort */ trynumeric: errno = 0; lscopeid = strtoul(scope, &ep, 10); *scopeid = (u_int32_t)(lscopeid & 0xffffffffUL); if (errno == 0 && ep && *ep == '\0' && *scopeid == lscopeid) return 0; else return -1; } #endif #ifdef NS_CACHING static int addrinfo_id_func(char *buffer, size_t *buffer_size, va_list ap, void *cache_mdata) { res_state statp; u_long res_options; const int op_id = 0; /* identifies the getaddrinfo for the cache */ char *hostname; struct addrinfo *hints; char *p; int ai_flags, ai_family, ai_socktype, ai_protocol; size_t desired_size, size; statp = __res_state(); res_options = statp->options & (RES_RECURSE | RES_DEFNAMES | RES_DNSRCH | RES_NOALIASES | RES_USE_INET6); hostname = va_arg(ap, char *); hints = va_arg(ap, struct addrinfo *); desired_size = sizeof(res_options) + sizeof(int) + sizeof(int) * 4; if (hostname != NULL) { size = strlen(hostname); desired_size += size + 1; } else size = 0; if (desired_size > *buffer_size) { *buffer_size = desired_size; return (NS_RETURN); } if (hints == NULL) ai_flags = ai_family = ai_socktype = ai_protocol = 0; else { ai_flags = hints->ai_flags; ai_family = hints->ai_family; ai_socktype = hints->ai_socktype; ai_protocol = hints->ai_protocol; } p = buffer; memcpy(p, &res_options, sizeof(res_options)); p += sizeof(res_options); memcpy(p, &op_id, sizeof(int)); p += sizeof(int); memcpy(p, &ai_flags, sizeof(int)); p += sizeof(int); memcpy(p, &ai_family, sizeof(int)); p += sizeof(int); memcpy(p, &ai_socktype, sizeof(int)); p += sizeof(int); memcpy(p, &ai_protocol, sizeof(int)); p += sizeof(int); if (hostname != NULL) memcpy(p, hostname, size); *buffer_size = desired_size; return (NS_SUCCESS); } static int addrinfo_marshal_func(char *buffer, size_t *buffer_size, void *retval, va_list ap, void *cache_mdata) { struct addrinfo *ai, *cai; char *p; size_t desired_size, size, ai_size; ai = *((struct addrinfo **)retval); desired_size = sizeof(size_t); ai_size = 0; for (cai = ai; cai != NULL; cai = cai->ai_next) { desired_size += sizeof(struct addrinfo) + cai->ai_addrlen; if (cai->ai_canonname != NULL) desired_size += sizeof(size_t) + strlen(cai->ai_canonname); ++ai_size; } if (desired_size > *buffer_size) { /* this assignment is here for future use */ errno = ERANGE; *buffer_size = desired_size; return (NS_RETURN); } memset(buffer, 0, desired_size); p = buffer; memcpy(p, &ai_size, sizeof(size_t)); p += sizeof(size_t); for (cai = ai; cai != NULL; cai = cai->ai_next) { memcpy(p, cai, sizeof(struct addrinfo)); p += sizeof(struct addrinfo); memcpy(p, cai->ai_addr, cai->ai_addrlen); p += cai->ai_addrlen; if (cai->ai_canonname != NULL) { size = strlen(cai->ai_canonname); memcpy(p, &size, sizeof(size_t)); p += sizeof(size_t); memcpy(p, cai->ai_canonname, size); p += size; } } return (NS_SUCCESS); } static int addrinfo_unmarshal_func(char *buffer, size_t buffer_size, void *retval, va_list ap, void *cache_mdata) { struct addrinfo new_ai, *result, *sentinel, *lasts; char *p; size_t ai_size, ai_i, size; p = buffer; memcpy(&ai_size, p, sizeof(size_t)); p += sizeof(size_t); result = NULL; lasts = NULL; for (ai_i = 0; ai_i < ai_size; ++ai_i) { memcpy(&new_ai, p, sizeof(struct addrinfo)); p += sizeof(struct addrinfo); size = new_ai.ai_addrlen + sizeof(struct addrinfo) + _ALIGNBYTES; sentinel = (struct addrinfo *)malloc(size); memset(sentinel, 0, size); memcpy(sentinel, &new_ai, sizeof(struct addrinfo)); sentinel->ai_addr = (struct sockaddr *)_ALIGN((char *)sentinel + sizeof(struct addrinfo)); memcpy(sentinel->ai_addr, p, new_ai.ai_addrlen); p += new_ai.ai_addrlen; if (new_ai.ai_canonname != NULL) { memcpy(&size, p, sizeof(size_t)); p += sizeof(size_t); sentinel->ai_canonname = (char *)malloc(size + 1); memset(sentinel->ai_canonname, 0, size + 1); memcpy(sentinel->ai_canonname, p, size); p += size; } if (result == NULL) { result = sentinel; lasts = sentinel; } else { lasts->ai_next = sentinel; lasts = sentinel; } } *((struct addrinfo **)retval) = result; return (NS_SUCCESS); } #endif /* NS_CACHING */ /* * FQDN hostname, DNS lookup */ static int explore_fqdn(const struct addrinfo *pai, const char *hostname, const char *servname, struct addrinfo **res) { struct addrinfo *result; struct addrinfo *cur; int error = 0; #ifdef NS_CACHING static const nss_cache_info cache_info = NS_COMMON_CACHE_INFO_INITIALIZER( hosts, NULL, addrinfo_id_func, addrinfo_marshal_func, addrinfo_unmarshal_func); #endif static const ns_dtab dtab[] = { NS_FILES_CB(_files_getaddrinfo, NULL) { NSSRC_DNS, _dns_getaddrinfo, NULL }, /* force -DHESIOD */ NS_NIS_CB(_yp_getaddrinfo, NULL) #ifdef NS_CACHING NS_CACHE_CB(&cache_info) #endif { 0 } }; result = NULL; /* * if the servname does not match socktype/protocol, ignore it. */ if (get_portmatch(pai, servname) != 0) return 0; switch (_nsdispatch(&result, dtab, NSDB_HOSTS, "getaddrinfo", default_dns_files, hostname, pai)) { case NS_TRYAGAIN: error = EAI_AGAIN; goto free; case NS_UNAVAIL: error = EAI_FAIL; goto free; case NS_NOTFOUND: error = EAI_NONAME; goto free; case NS_SUCCESS: error = 0; for (cur = result; cur; cur = cur->ai_next) { GET_PORT(cur, servname); /* canonname should be filled already */ } break; } *res = result; return 0; free: if (result) freeaddrinfo(result); return error; } #ifdef DEBUG static const char AskedForGot[] = "gethostby*.getanswer: asked for \"%s\", got \"%s\""; #endif static struct addrinfo * getanswer(const querybuf *answer, int anslen, const char *qname, int qtype, const struct addrinfo *pai, res_state res) { struct addrinfo sentinel, *cur; struct addrinfo ai; const struct afd *afd; char *canonname; const HEADER *hp; const u_char *cp; int n; const u_char *eom; char *bp, *ep; int type, class, ancount, qdcount; int haveanswer, had_error; char tbuf[MAXDNAME]; int (*name_ok)(const char *); char hostbuf[8*1024]; memset(&sentinel, 0, sizeof(sentinel)); cur = &sentinel; canonname = NULL; eom = answer->buf + anslen; switch (qtype) { case T_A: case T_AAAA: case T_ANY: /*use T_ANY only for T_A/T_AAAA lookup*/ name_ok = res_hnok; break; default: return (NULL); /* XXX should be abort(); */ } /* * find first satisfactory answer */ hp = &answer->hdr; ancount = ntohs(hp->ancount); qdcount = ntohs(hp->qdcount); bp = hostbuf; ep = hostbuf + sizeof hostbuf; cp = answer->buf + HFIXEDSZ; if (qdcount != 1) { RES_SET_H_ERRNO(res, NO_RECOVERY); return (NULL); } n = dn_expand(answer->buf, eom, cp, bp, ep - bp); if ((n < 0) || !(*name_ok)(bp)) { RES_SET_H_ERRNO(res, NO_RECOVERY); return (NULL); } cp += n + QFIXEDSZ; if (qtype == T_A || qtype == T_AAAA || qtype == T_ANY) { /* res_send() has already verified that the query name is the * same as the one we sent; this just gets the expanded name * (i.e., with the succeeding search-domain tacked on). */ n = strlen(bp) + 1; /* for the \0 */ if (n >= MAXHOSTNAMELEN) { RES_SET_H_ERRNO(res, NO_RECOVERY); return (NULL); } canonname = bp; bp += n; /* The qname can be abbreviated, but h_name is now absolute. */ qname = canonname; } haveanswer = 0; had_error = 0; while (ancount-- > 0 && cp < eom && !had_error) { n = dn_expand(answer->buf, eom, cp, bp, ep - bp); if ((n < 0) || !(*name_ok)(bp)) { had_error++; continue; } cp += n; /* name */ type = _getshort(cp); cp += INT16SZ; /* type */ class = _getshort(cp); cp += INT16SZ + INT32SZ; /* class, TTL */ n = _getshort(cp); cp += INT16SZ; /* len */ if (class != C_IN) { /* XXX - debug? syslog? */ cp += n; continue; /* XXX - had_error++ ? */ } if ((qtype == T_A || qtype == T_AAAA || qtype == T_ANY) && type == T_CNAME) { n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf); if ((n < 0) || !(*name_ok)(tbuf)) { had_error++; continue; } cp += n; /* Get canonical name. */ n = strlen(tbuf) + 1; /* for the \0 */ if (n > ep - bp || n >= MAXHOSTNAMELEN) { had_error++; continue; } strlcpy(bp, tbuf, ep - bp); canonname = bp; bp += n; continue; } if (qtype == T_ANY) { if (!(type == T_A || type == T_AAAA)) { cp += n; continue; } } else if (type != qtype) { #ifdef DEBUG if (type != T_KEY && type != T_SIG && type != ns_t_dname) syslog(LOG_NOTICE|LOG_AUTH, "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"", qname, p_class(C_IN), p_type(qtype), p_type(type)); #endif cp += n; continue; /* XXX - had_error++ ? */ } switch (type) { case T_A: case T_AAAA: if (strcasecmp(canonname, bp) != 0) { #ifdef DEBUG syslog(LOG_NOTICE|LOG_AUTH, AskedForGot, canonname, bp); #endif cp += n; continue; /* XXX - had_error++ ? */ } if (type == T_A && n != INADDRSZ) { cp += n; continue; } if (type == T_AAAA && n != IN6ADDRSZ) { cp += n; continue; } #ifdef FILTER_V4MAPPED if (type == T_AAAA) { struct in6_addr in6; memcpy(&in6, cp, sizeof(in6)); if (IN6_IS_ADDR_V4MAPPED(&in6)) { cp += n; continue; } } #endif if (!haveanswer) { int nn; canonname = bp; nn = strlen(bp) + 1; /* for the \0 */ bp += nn; } /* don't overwrite pai */ ai = *pai; ai.ai_family = (type == T_A) ? AF_INET : AF_INET6; afd = find_afd(ai.ai_family); if (afd == NULL) { cp += n; continue; } cur->ai_next = get_ai(&ai, afd, (const char *)cp); if (cur->ai_next == NULL) had_error++; while (cur && cur->ai_next) cur = cur->ai_next; cp += n; break; default: abort(); } if (!had_error) haveanswer++; } if (haveanswer) { #if defined(RESOLVSORT) /* * We support only IPv4 address for backward * compatibility against gethostbyname(3). */ if (res->nsort && qtype == T_A) { if (addr4sort(&sentinel, res) < 0) { freeaddrinfo(sentinel.ai_next); RES_SET_H_ERRNO(res, NO_RECOVERY); return NULL; } } #endif /*RESOLVSORT*/ if (!canonname) (void)get_canonname(pai, sentinel.ai_next, qname); else (void)get_canonname(pai, sentinel.ai_next, canonname); RES_SET_H_ERRNO(res, NETDB_SUCCESS); return sentinel.ai_next; } - RES_SET_H_ERRNO(res, NO_RECOVERY); + /* + * We could have walked a CNAME chain, but the ultimate target + * may not have what we looked for. + */ + RES_SET_H_ERRNO(res, ntohs(hp->ancount) > 0 ? NO_DATA : NO_RECOVERY); return NULL; } #ifdef RESOLVSORT struct addr_ptr { struct addrinfo *ai; int aval; }; static int addr4sort(struct addrinfo *sentinel, res_state res) { struct addrinfo *ai; struct addr_ptr *addrs, addr; struct sockaddr_in *sin; int naddrs, i, j; int needsort = 0; if (!sentinel) return -1; naddrs = 0; for (ai = sentinel->ai_next; ai; ai = ai->ai_next) naddrs++; if (naddrs < 2) return 0; /* We don't need sorting. */ if ((addrs = malloc(sizeof(struct addr_ptr) * naddrs)) == NULL) return -1; i = 0; for (ai = sentinel->ai_next; ai; ai = ai->ai_next) { sin = (struct sockaddr_in *)ai->ai_addr; for (j = 0; (unsigned)j < res->nsort; j++) { if (res->sort_list[j].addr.s_addr == (sin->sin_addr.s_addr & res->sort_list[j].mask)) break; } addrs[i].ai = ai; addrs[i].aval = j; if (needsort == 0 && i > 0 && j < addrs[i - 1].aval) needsort = i; i++; } if (!needsort) { free(addrs); return 0; } while (needsort < naddrs) { for (j = needsort - 1; j >= 0; j--) { if (addrs[j].aval > addrs[j+1].aval) { addr = addrs[j]; addrs[j] = addrs[j + 1]; addrs[j + 1] = addr; } else break; } needsort++; } ai = sentinel; for (i = 0; i < naddrs; ++i) { ai->ai_next = addrs[i].ai; ai = ai->ai_next; } ai->ai_next = NULL; free(addrs); return 0; } #endif /*RESOLVSORT*/ /*ARGSUSED*/ static int _dns_getaddrinfo(void *rv, void *cb_data, va_list ap) { - struct addrinfo *ai; + struct addrinfo *ai, ai0; querybuf *buf, *buf2; const char *hostname; const struct addrinfo *pai; struct addrinfo sentinel, *cur; struct res_target q, q2; res_state res; hostname = va_arg(ap, char *); pai = va_arg(ap, const struct addrinfo *); memset(&q, 0, sizeof(q)); memset(&q2, 0, sizeof(q2)); memset(&sentinel, 0, sizeof(sentinel)); cur = &sentinel; res = __res_state(); buf = malloc(sizeof(*buf)); if (!buf) { RES_SET_H_ERRNO(res, NETDB_INTERNAL); return NS_NOTFOUND; } buf2 = malloc(sizeof(*buf2)); if (!buf2) { free(buf); RES_SET_H_ERRNO(res, NETDB_INTERNAL); return NS_NOTFOUND; } + if (pai->ai_family == AF_INET6 && + (pai->ai_flags & AI_V4MAPPED) == AI_V4MAPPED) { + ai0 = *pai; + ai0.ai_family = AF_UNSPEC; + pai = &ai0; + } + switch (pai->ai_family) { case AF_UNSPEC: q.name = hostname; q.qclass = C_IN; q.qtype = T_A; q.answer = buf->buf; q.anslen = sizeof(buf->buf); q.next = &q2; q2.name = hostname; q2.qclass = C_IN; q2.qtype = T_AAAA; q2.answer = buf2->buf; q2.anslen = sizeof(buf2->buf); break; case AF_INET: q.name = hostname; q.qclass = C_IN; q.qtype = T_A; q.answer = buf->buf; q.anslen = sizeof(buf->buf); break; case AF_INET6: q.name = hostname; q.qclass = C_IN; q.qtype = T_AAAA; q.answer = buf->buf; q.anslen = sizeof(buf->buf); break; default: free(buf); free(buf2); return NS_UNAVAIL; } if ((res->options & RES_INIT) == 0 && res_ninit(res) == -1) { RES_SET_H_ERRNO(res, NETDB_INTERNAL); free(buf); free(buf2); return NS_NOTFOUND; } if (res_searchN(hostname, &q, res) < 0) { free(buf); free(buf2); return NS_NOTFOUND; } /* prefer IPv6 */ if (q.next) { ai = getanswer(buf2, q2.n, q2.name, q2.qtype, pai, res); if (ai) { cur->ai_next = ai; while (cur && cur->ai_next) cur = cur->ai_next; } } - ai = getanswer(buf, q.n, q.name, q.qtype, pai, res); - if (ai) - cur->ai_next = ai; + if (!ai || pai->ai_family != AF_UNSPEC || + (pai->ai_flags & (AI_ALL | AI_V4MAPPED)) != AI_V4MAPPED) { + ai = getanswer(buf, q.n, q.name, q.qtype, pai, res); + if (ai) + cur->ai_next = ai; + } free(buf); free(buf2); if (sentinel.ai_next == NULL) switch (res->res_h_errno) { case HOST_NOT_FOUND: + case NO_DATA: return NS_NOTFOUND; case TRY_AGAIN: return NS_TRYAGAIN; default: return NS_UNAVAIL; } *((struct addrinfo **)rv) = sentinel.ai_next; return NS_SUCCESS; } static void _sethtent(FILE **hostf) { if (!*hostf) *hostf = fopen(_PATH_HOSTS, "re"); else rewind(*hostf); } static void _endhtent(FILE **hostf) { if (*hostf) { (void) fclose(*hostf); *hostf = NULL; } } static struct addrinfo * _gethtent(FILE **hostf, const char *name, const struct addrinfo *pai) { char *p; char *cp, *tname, *cname; struct addrinfo hints, *res0, *res; int error; const char *addr; char hostbuf[8*1024]; if (!*hostf && !(*hostf = fopen(_PATH_HOSTS, "re"))) return (NULL); again: if (!(p = fgets(hostbuf, sizeof hostbuf, *hostf))) return (NULL); if (*p == '#') goto again; cp = strpbrk(p, "#\n"); if (cp != NULL) *cp = '\0'; if (!(cp = strpbrk(p, " \t"))) goto again; *cp++ = '\0'; addr = p; cname = NULL; /* if this is not something we're looking for, skip it. */ while (cp && *cp) { if (*cp == ' ' || *cp == '\t') { cp++; continue; } tname = cp; if (cname == NULL) cname = cp; if ((cp = strpbrk(cp, " \t")) != NULL) *cp++ = '\0'; if (strcasecmp(name, tname) == 0) goto found; } goto again; found: /* we should not glob socktype/protocol here */ memset(&hints, 0, sizeof(hints)); hints.ai_family = pai->ai_family; hints.ai_socktype = SOCK_DGRAM; hints.ai_protocol = 0; hints.ai_flags = AI_NUMERICHOST; + if (pai->ai_family == AF_INET6 && + (pai->ai_flags & AI_V4MAPPED) == AI_V4MAPPED) + hints.ai_flags |= AI_V4MAPPED; error = getaddrinfo(addr, "0", &hints, &res0); if (error) goto again; #ifdef FILTER_V4MAPPED /* XXX should check all items in the chain */ if (res0->ai_family == AF_INET6 && IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)res0->ai_addr)->sin6_addr)) { freeaddrinfo(res0); goto again; } #endif for (res = res0; res; res = res->ai_next) { /* cover it up */ res->ai_flags = pai->ai_flags; res->ai_socktype = pai->ai_socktype; res->ai_protocol = pai->ai_protocol; if (pai->ai_flags & AI_CANONNAME) { if (get_canonname(pai, res, cname) != 0) { freeaddrinfo(res0); goto again; } } } return res0; } +static struct addrinfo * +_getht(FILE **hostf, const char *name, const struct addrinfo *pai, + struct addrinfo *cur) +{ + struct addrinfo *p; + + while ((p = _gethtent(hostf, name, pai)) != NULL) { + cur->ai_next = p; + while (cur && cur->ai_next) + cur = cur->ai_next; + } + return (cur); +} + /*ARGSUSED*/ static int _files_getaddrinfo(void *rv, void *cb_data, va_list ap) { const char *name; const struct addrinfo *pai; struct addrinfo sentinel, *cur; - struct addrinfo *p; FILE *hostf = NULL; name = va_arg(ap, char *); pai = va_arg(ap, struct addrinfo *); memset(&sentinel, 0, sizeof(sentinel)); cur = &sentinel; _sethtent(&hostf); - while ((p = _gethtent(&hostf, name, pai)) != NULL) { - cur->ai_next = p; - while (cur && cur->ai_next) - cur = cur->ai_next; - } + if (pai->ai_family == AF_INET6 && + (pai->ai_flags & (AI_ALL | AI_V4MAPPED)) == AI_V4MAPPED) { + struct addrinfo ai0 = *pai; + + ai0.ai_flags &= ~AI_V4MAPPED; + cur = _getht(&hostf, name, &ai0, cur); + if (sentinel.ai_next == NULL) { + _sethtent(&hostf); + ai0.ai_flags |= AI_V4MAPPED; + cur = _getht(&hostf, name, &ai0, cur); + } + } else + cur = _getht(&hostf, name, pai, cur); _endhtent(&hostf); *((struct addrinfo **)rv) = sentinel.ai_next; if (sentinel.ai_next == NULL) return NS_NOTFOUND; return NS_SUCCESS; } #ifdef YP /*ARGSUSED*/ static struct addrinfo * _yphostent(char *line, const struct addrinfo *pai) { struct addrinfo sentinel, *cur; struct addrinfo hints, *res, *res0; int error; char *p = line; const char *addr, *canonname; char *nextline; char *cp; addr = canonname = NULL; memset(&sentinel, 0, sizeof(sentinel)); cur = &sentinel; nextline: /* terminate line */ cp = strchr(p, '\n'); if (cp) { *cp++ = '\0'; nextline = cp; } else nextline = NULL; cp = strpbrk(p, " \t"); if (cp == NULL) { if (canonname == NULL) return (NULL); else goto done; } *cp++ = '\0'; addr = p; while (cp && *cp) { if (*cp == ' ' || *cp == '\t') { cp++; continue; } if (!canonname) canonname = cp; if ((cp = strpbrk(cp, " \t")) != NULL) *cp++ = '\0'; } hints = *pai; hints.ai_flags = AI_NUMERICHOST; + if (pai->ai_family == AF_INET6 && + (pai->ai_flags & AI_V4MAPPED) == AI_V4MAPPED) + hints.ai_flags |= AI_V4MAPPED; error = getaddrinfo(addr, NULL, &hints, &res0); if (error == 0) { for (res = res0; res; res = res->ai_next) { /* cover it up */ res->ai_flags = pai->ai_flags; if (pai->ai_flags & AI_CANONNAME) (void)get_canonname(pai, res, canonname); } } else res0 = NULL; if (res0) { cur->ai_next = res0; while (cur && cur->ai_next) cur = cur->ai_next; } if (nextline) { p = nextline; goto nextline; } done: return sentinel.ai_next; } /*ARGSUSED*/ static int _yp_getaddrinfo(void *rv, void *cb_data, va_list ap) { struct addrinfo sentinel, *cur; struct addrinfo *ai = NULL; char *ypbuf; int ypbuflen, r; const char *name; const struct addrinfo *pai; char *ypdomain; if (_yp_check(&ypdomain) == 0) return NS_UNAVAIL; name = va_arg(ap, char *); pai = va_arg(ap, const struct addrinfo *); memset(&sentinel, 0, sizeof(sentinel)); cur = &sentinel; + /* ipnodes.byname can hold both IPv4/v6 */ + r = yp_match(ypdomain, "ipnodes.byname", name, + (int)strlen(name), &ypbuf, &ypbuflen); + if (r == 0) { + ai = _yphostent(ypbuf, pai); + if (ai) { + cur->ai_next = ai; + while (cur && cur->ai_next) + cur = cur->ai_next; + } + free(ypbuf); + } + + if (ai != NULL) { + struct sockaddr_in6 *sin6; + + switch (ai->ai_family) { + case AF_INET: + goto done; + case AF_INET6: + sin6 = (struct sockaddr_in6 *)ai->ai_addr; + if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) + goto done; + break; + } + } + /* hosts.byname is only for IPv4 (Solaris8) */ - if (pai->ai_family == PF_UNSPEC || pai->ai_family == PF_INET) { + if (pai->ai_family == AF_UNSPEC || pai->ai_family == AF_INET || + ((pai->ai_family == AF_INET6 && + (pai->ai_flags & AI_V4MAPPED) == AI_V4MAPPED) && + (ai == NULL || (pai->ai_flags & AI_ALL) == AI_ALL))) { r = yp_match(ypdomain, "hosts.byname", name, (int)strlen(name), &ypbuf, &ypbuflen); if (r == 0) { struct addrinfo ai4; ai4 = *pai; - ai4.ai_family = AF_INET; + if (pai->ai_family == AF_UNSPEC) + ai4.ai_family = AF_INET; ai = _yphostent(ypbuf, &ai4); if (ai) { cur->ai_next = ai; while (cur && cur->ai_next) cur = cur->ai_next; } free(ypbuf); } } - /* ipnodes.byname can hold both IPv4/v6 */ - r = yp_match(ypdomain, "ipnodes.byname", name, - (int)strlen(name), &ypbuf, &ypbuflen); - if (r == 0) { - ai = _yphostent(ypbuf, pai); - if (ai) - cur->ai_next = ai; - free(ypbuf); - } - +done: if (sentinel.ai_next == NULL) { RES_SET_H_ERRNO(__res_state(), HOST_NOT_FOUND); return NS_NOTFOUND; } *((struct addrinfo **)rv) = sentinel.ai_next; return NS_SUCCESS; } #endif /* resolver logic */ /* * Formulate a normal query, send, and await answer. * Returned answer is placed in supplied buffer "answer". * Perform preliminary check of answer, returning success only * if no error is indicated and the answer count is nonzero. * Return the size of the response on success, -1 on error. * Error number is left in h_errno. * * Caller must parse answer and determine whether it answers the question. */ static int res_queryN(const char *name, struct res_target *target, res_state res) { u_char *buf; HEADER *hp; int n; u_int oflags; struct res_target *t; int rcode; int ancount; rcode = NOERROR; ancount = 0; buf = malloc(MAXPACKET); if (!buf) { RES_SET_H_ERRNO(res, NETDB_INTERNAL); return -1; } for (t = target; t; t = t->next) { int class, type; u_char *answer; int anslen; hp = (HEADER *)(void *)t->answer; /* make it easier... */ class = t->qclass; type = t->qtype; answer = t->answer; anslen = t->anslen; oflags = res->_flags; again: hp->rcode = NOERROR; /* default */ #ifdef DEBUG if (res->options & RES_DEBUG) printf(";; res_query(%s, %d, %d)\n", name, class, type); #endif n = res_nmkquery(res, QUERY, name, class, type, NULL, 0, NULL, buf, MAXPACKET); if (n > 0 && (res->_flags & RES_F_EDNS0ERR) == 0 && (res->options & (RES_USE_EDNS0|RES_USE_DNSSEC)) != 0U) n = res_nopt(res, n, buf, MAXPACKET, anslen); if (n <= 0) { #ifdef DEBUG if (res->options & RES_DEBUG) printf(";; res_query: mkquery failed\n"); #endif free(buf); RES_SET_H_ERRNO(res, NO_RECOVERY); return (n); } n = res_nsend(res, buf, n, answer, anslen); if (n < 0) { /* * if the query choked with EDNS0, retry * without EDNS0 */ if ((res->options & (RES_USE_EDNS0|RES_USE_DNSSEC)) != 0U && ((oflags ^ res->_flags) & RES_F_EDNS0ERR) != 0) { res->_flags |= RES_F_EDNS0ERR; if (res->options & RES_DEBUG) printf(";; res_nquery: retry without EDNS0\n"); goto again; } rcode = hp->rcode; /* record most recent error */ #ifdef DEBUG if (res->options & RES_DEBUG) printf(";; res_query: send error\n"); #endif continue; } if (n > anslen) hp->rcode = FORMERR; /* XXX not very informative */ if (hp->rcode != NOERROR || ntohs(hp->ancount) == 0) { rcode = hp->rcode; /* record most recent error */ #ifdef DEBUG if (res->options & RES_DEBUG) printf(";; rcode = %u, ancount=%u\n", hp->rcode, ntohs(hp->ancount)); #endif continue; } ancount += ntohs(hp->ancount); t->n = n; } free(buf); if (ancount == 0) { switch (rcode) { case NXDOMAIN: RES_SET_H_ERRNO(res, HOST_NOT_FOUND); break; case SERVFAIL: RES_SET_H_ERRNO(res, TRY_AGAIN); break; case NOERROR: RES_SET_H_ERRNO(res, NO_DATA); break; case FORMERR: case NOTIMP: case REFUSED: default: RES_SET_H_ERRNO(res, NO_RECOVERY); break; } return (-1); } return (ancount); } /* * Formulate a normal query, send, and retrieve answer in supplied buffer. * Return the size of the response on success, -1 on error. * If enabled, implement search rules until answer or unrecoverable failure * is detected. Error code, if any, is left in h_errno. */ static int res_searchN(const char *name, struct res_target *target, res_state res) { const char *cp, * const *domain; HEADER *hp = (HEADER *)(void *)target->answer; /*XXX*/ u_int dots; int trailing_dot, ret, saved_herrno; int got_nodata = 0, got_servfail = 0, root_on_list = 0; int tried_as_is = 0; int searched = 0; char abuf[MAXDNAME]; errno = 0; RES_SET_H_ERRNO(res, HOST_NOT_FOUND); /* default, if we never query */ dots = 0; for (cp = name; *cp; cp++) dots += (*cp == '.'); trailing_dot = 0; if (cp > name && *--cp == '.') trailing_dot++; /* * if there aren't any dots, it could be a user-level alias */ if (!dots && (cp = res_hostalias(res, name, abuf, sizeof(abuf))) != NULL) return (res_queryN(cp, target, res)); /* * If there are enough dots in the name, let's just give it a * try 'as is'. The threshold can be set with the "ndots" option. * Also, query 'as is', if there is a trailing dot in the name. */ saved_herrno = -1; if (dots >= res->ndots || trailing_dot) { ret = res_querydomainN(name, NULL, target, res); if (ret > 0 || trailing_dot) return (ret); if (errno == ECONNREFUSED) { RES_SET_H_ERRNO(res, TRY_AGAIN); return (-1); } switch (res->res_h_errno) { case NO_DATA: case HOST_NOT_FOUND: break; case TRY_AGAIN: if (hp->rcode == SERVFAIL) break; /* FALLTHROUGH */ default: return (-1); } saved_herrno = res->res_h_errno; tried_as_is++; } /* * We do at least one level of search if * - there is no dot and RES_DEFNAME is set, or * - there is at least one dot, there is no trailing dot, * and RES_DNSRCH is set. */ if ((!dots && (res->options & RES_DEFNAMES)) || (dots && !trailing_dot && (res->options & RES_DNSRCH))) { int done = 0; for (domain = (const char * const *)res->dnsrch; *domain && !done; domain++) { searched = 1; if (domain[0][0] == '\0' || (domain[0][0] == '.' && domain[0][1] == '\0')) root_on_list++; if (root_on_list && tried_as_is) continue; ret = res_querydomainN(name, *domain, target, res); if (ret > 0) return (ret); /* * If no server present, give up. * If name isn't found in this domain, * keep trying higher domains in the search list * (if that's enabled). * On a NO_DATA error, keep trying, otherwise * a wildcard entry of another type could keep us * from finding this entry higher in the domain. * If we get some other error (negative answer or * server failure), then stop searching up, * but try the input name below in case it's * fully-qualified. */ if (errno == ECONNREFUSED) { RES_SET_H_ERRNO(res, TRY_AGAIN); return (-1); } switch (res->res_h_errno) { case NO_DATA: got_nodata++; /* FALLTHROUGH */ case HOST_NOT_FOUND: /* keep trying */ break; case TRY_AGAIN: got_servfail++; if (hp->rcode == SERVFAIL) { /* try next search element, if any */ break; } /* FALLTHROUGH */ default: /* anything else implies that we're done */ done++; } /* * if we got here for some reason other than DNSRCH, * we only wanted one iteration of the loop, so stop. */ if (!(res->options & RES_DNSRCH)) done++; } } switch (res->res_h_errno) { case NO_DATA: case HOST_NOT_FOUND: break; case TRY_AGAIN: if (hp->rcode == SERVFAIL) break; /* FALLTHROUGH */ default: goto giveup; } /* * If the query has not already been tried as is then try it * unless RES_NOTLDQUERY is set and there were no dots. */ if ((dots || !searched || !(res->options & RES_NOTLDQUERY)) && !(tried_as_is || root_on_list)) { ret = res_querydomainN(name, NULL, target, res); if (ret > 0) return (ret); } /* * if we got here, we didn't satisfy the search. * if we did an initial full query, return that query's h_errno * (note that we wouldn't be here if that query had succeeded). * else if we ever got a nodata, send that back as the reason. * else send back meaningless h_errno, that being the one from * the last DNSRCH we did. */ giveup: if (saved_herrno != -1) RES_SET_H_ERRNO(res, saved_herrno); else if (got_nodata) RES_SET_H_ERRNO(res, NO_DATA); else if (got_servfail) RES_SET_H_ERRNO(res, TRY_AGAIN); return (-1); } /* * Perform a call on res_query on the concatenation of name and domain, * removing a trailing dot from name if domain is NULL. */ static int res_querydomainN(const char *name, const char *domain, struct res_target *target, res_state res) { char nbuf[MAXDNAME]; const char *longname = nbuf; size_t n, d; #ifdef DEBUG if (res->options & RES_DEBUG) printf(";; res_querydomain(%s, %s)\n", name, domain?domain:""); #endif if (domain == NULL) { /* * Check for trailing '.'; * copy without '.' if present. */ n = strlen(name); if (n >= MAXDNAME) { RES_SET_H_ERRNO(res, NO_RECOVERY); return (-1); } if (n > 0 && name[--n] == '.') { strncpy(nbuf, name, n); nbuf[n] = '\0'; } else longname = name; } else { n = strlen(name); d = strlen(domain); if (n + d + 1 >= MAXDNAME) { RES_SET_H_ERRNO(res, NO_RECOVERY); return (-1); } snprintf(nbuf, sizeof(nbuf), "%s.%s", name, domain); } return (res_queryN(longname, target, res)); } Index: user/ngie/stable-10-libnv/lib/libc/net/map_v4v6.c =================================================================== --- user/ngie/stable-10-libnv/lib/libc/net/map_v4v6.c (revision 292856) +++ user/ngie/stable-10-libnv/lib/libc/net/map_v4v6.c (revision 292857) @@ -1,119 +1,111 @@ /* * ++Copyright++ 1985, 1988, 1993 * - * Copyright (c) 1985, 1988, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * Portions Copyright (c) 1993 by Digital Equipment Corporation. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies, and that * the name of Digital Equipment Corporation not be used in advertising or * publicity pertaining to distribution of the document or software without * specific, written prior permission. * * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. * - * --Copyright-- */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)gethostnamadr.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include typedef union { int32_t al; char ac; } align; void _map_v4v6_address(const char *src, char *dst) { - u_char *p = (u_char *)dst; - char tmp[NS_INADDRSZ]; - int i; - - /* Stash a temporary copy so our caller can update in place. */ - memcpy(tmp, src, NS_INADDRSZ); + /* Our caller may update in place. */ + memmove(&dst[12], src, NS_INADDRSZ); /* Mark this ipv6 addr as a mapped ipv4. */ - for (i = 0; i < 10; i++) - *p++ = 0x00; - *p++ = 0xff; - *p++ = 0xff; - /* Retrieve the saved copy and we're done. */ - memcpy((void*)p, tmp, NS_INADDRSZ); + memset(&dst[10], 0xff, 2); + memset(&dst[0], 0, 10); } void _map_v4v6_hostent(struct hostent *hp, char **bpp, char *ep) { char **ap; if (hp->h_addrtype != AF_INET || hp->h_length != INADDRSZ) return; hp->h_addrtype = AF_INET6; hp->h_length = IN6ADDRSZ; for (ap = hp->h_addr_list; *ap; ap++) { int i = (u_long)*bpp % sizeof(align); if (i != 0) i = sizeof(align) - i; if ((ep - *bpp) < (i + IN6ADDRSZ)) { /* Out of memory. Truncate address list here. */ *ap = NULL; return; } *bpp += i; _map_v4v6_address(*ap, *bpp); *ap = *bpp; *bpp += IN6ADDRSZ; } } Index: user/ngie/stable-10-libnv/lib/libc/net/name6.c =================================================================== --- user/ngie/stable-10-libnv/lib/libc/net/name6.c (revision 292856) +++ user/ngie/stable-10-libnv/lib/libc/net/name6.c (revision 292857) @@ -1,1114 +1,1113 @@ /* $KAME: name6.c,v 1.25 2000/06/26 16:44:40 itojun Exp $ */ /* * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * ++Copyright++ 1985, 1988, 1993 * - * Copyright (c) 1985, 1988, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * Portions Copyright (c) 1993 by Digital Equipment Corporation. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies, and that * the name of Digital Equipment Corporation not be used in advertising or * publicity pertaining to distribution of the document or software without * specific, written prior permission. * * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. * - * --Copyright-- */ /* * Atsushi Onoe */ #include __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include #include #include #include #ifdef INET6 #include #include #include #include #include /* XXX */ #endif #include #include #include #include #include #include #include #include #include #include #include #include "un-namespace.h" #include "netdb_private.h" #include "res_private.h" #ifndef MAXALIASES #define MAXALIASES 10 #endif #ifndef MAXADDRS #define MAXADDRS 20 #endif #ifndef MAXDNAME #define MAXDNAME 1025 #endif #ifdef INET6 #define ADDRLEN(af) ((af) == AF_INET6 ? sizeof(struct in6_addr) : \ sizeof(struct in_addr)) #else #define ADDRLEN(af) sizeof(struct in_addr) #endif #define MAPADDR(ab, ina) \ do { \ memcpy(&(ab)->map_inaddr, ina, sizeof(struct in_addr)); \ memset((ab)->map_zero, 0, sizeof((ab)->map_zero)); \ memset((ab)->map_one, 0xff, sizeof((ab)->map_one)); \ } while (0) #define MAPADDRENABLED(flags) \ (((flags) & AI_V4MAPPED) || \ (((flags) & AI_V4MAPPED_CFG))) union inx_addr { struct in_addr in_addr; #ifdef INET6 struct in6_addr in6_addr; #endif struct { u_char mau_zero[10]; u_char mau_one[2]; struct in_addr mau_inaddr; } map_addr_un; #define map_zero map_addr_un.mau_zero #define map_one map_addr_un.mau_one #define map_inaddr map_addr_un.mau_inaddr }; struct policyqueue { TAILQ_ENTRY(policyqueue) pc_entry; #ifdef INET6 struct in6_addrpolicy pc_policy; #endif }; TAILQ_HEAD(policyhead, policyqueue); #define AIO_SRCFLAG_DEPRECATED 0x1 struct hp_order { union { struct sockaddr_storage aiou_ss; struct sockaddr aiou_sa; } aio_src_un; #define aio_srcsa aio_src_un.aiou_sa u_int32_t aio_srcflag; int aio_srcscope; int aio_dstscope; struct policyqueue *aio_srcpolicy; struct policyqueue *aio_dstpolicy; union { struct sockaddr_storage aiou_ss; struct sockaddr aiou_sa; } aio_un; #define aio_sa aio_un.aiou_sa int aio_matchlen; char *aio_h_addr; }; static struct hostent *_hpcopy(struct hostent *, int *); static struct hostent *_hpaddr(int, const char *, void *, int *); #ifdef INET6 static struct hostent *_hpmerge(struct hostent *, struct hostent *, int *); static struct hostent *_hpmapv6(struct hostent *, int *); #endif static struct hostent *_hpsort(struct hostent *, res_state); #ifdef INET6 static struct hostent *_hpreorder(struct hostent *); static int get_addrselectpolicy(struct policyhead *); static void free_addrselectpolicy(struct policyhead *); static struct policyqueue *match_addrselectpolicy(struct sockaddr *, struct policyhead *); static void set_source(struct hp_order *, struct policyhead *); static int matchlen(struct sockaddr *, struct sockaddr *); static int comp_dst(const void *, const void *); static int gai_addr2scopetype(struct sockaddr *); #endif /* * Functions defined in RFC2553 * getipnodebyname, getipnodebyaddr, freehostent */ struct hostent * getipnodebyname(const char *name, int af, int flags, int *errp) { struct hostent *hp; union inx_addr addrbuf; res_state statp; u_long options; switch (af) { case AF_INET: #ifdef INET6 case AF_INET6: #endif break; default: *errp = NO_RECOVERY; return NULL; } if (flags & AI_ADDRCONFIG) { int s; if ((s = _socket(af, SOCK_DGRAM | SOCK_CLOEXEC, 0)) < 0) return NULL; /* * TODO: * Note that implementation dependent test for address * configuration should be done everytime called * (or apropriate interval), * because addresses will be dynamically assigned or deleted. */ _close(s); } #ifdef INET6 /* special case for literal address */ if (inet_pton(AF_INET6, name, &addrbuf) == 1) { if (af != AF_INET6) { *errp = HOST_NOT_FOUND; return NULL; } return _hpaddr(af, name, &addrbuf, errp); } #endif if (inet_aton(name, (struct in_addr *)&addrbuf) == 1) { if (af != AF_INET) { if (MAPADDRENABLED(flags)) { MAPADDR(&addrbuf, &addrbuf.in_addr); } else { *errp = HOST_NOT_FOUND; return NULL; } } return _hpaddr(af, name, &addrbuf, errp); } statp = __res_state(); if ((statp->options & RES_INIT) == 0) { if (res_ninit(statp) < 0) { *errp = NETDB_INTERNAL; return NULL; } } options = statp->options; statp->options &= ~RES_USE_INET6; hp = gethostbyname2(name, af); hp = _hpcopy(hp, errp); #ifdef INET6 if (af == AF_INET6) hp = _hpreorder(hp); if (af == AF_INET6 && ((flags & AI_ALL) || hp == NULL) && MAPADDRENABLED(flags)) { struct hostent *hp2 = gethostbyname2(name, AF_INET); if (hp == NULL) if (hp2 == NULL) *errp = statp->res_h_errno; else hp = _hpmapv6(hp2, errp); else { if (hp2 && strcmp(hp->h_name, hp2->h_name) == 0) { struct hostent *hpb = hp; hp = _hpmerge(hpb, hp2, errp); freehostent(hpb); } } } #endif if (hp == NULL) *errp = statp->res_h_errno; statp->options = options; return _hpsort(hp, statp); } struct hostent * getipnodebyaddr(const void *src, size_t len, int af, int *errp) { struct hostent *hp; res_state statp; u_long options; #ifdef INET6 struct in6_addr addrbuf; #else struct in_addr addrbuf; #endif switch (af) { case AF_INET: if (len != sizeof(struct in_addr)) { *errp = NO_RECOVERY; return NULL; } if ((long)src & ~(sizeof(struct in_addr) - 1)) { memcpy(&addrbuf, src, len); src = &addrbuf; } if (((struct in_addr *)src)->s_addr == 0) return NULL; break; #ifdef INET6 case AF_INET6: if (len != sizeof(struct in6_addr)) { *errp = NO_RECOVERY; return NULL; } if ((long)src & ~(sizeof(struct in6_addr) / 2 - 1)) { /*XXX*/ memcpy(&addrbuf, src, len); src = &addrbuf; } if (IN6_IS_ADDR_UNSPECIFIED((struct in6_addr *)src)) return NULL; if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)src) || IN6_IS_ADDR_V4COMPAT((struct in6_addr *)src)) { src = (char *)src + (sizeof(struct in6_addr) - sizeof(struct in_addr)); af = AF_INET; len = sizeof(struct in_addr); } break; #endif default: *errp = NO_RECOVERY; return NULL; } statp = __res_state(); if ((statp->options & RES_INIT) == 0) { if (res_ninit(statp) < 0) { RES_SET_H_ERRNO(statp, NETDB_INTERNAL); return NULL; } } options = statp->options; statp->options &= ~RES_USE_INET6; hp = gethostbyaddr(src, len, af); if (hp == NULL) *errp = statp->res_h_errno; statp->options = options; return (_hpcopy(hp, errp)); } void freehostent(struct hostent *ptr) { free(ptr); } /* * Private utility functions */ /* * _hpcopy: allocate and copy hostent structure */ static struct hostent * _hpcopy(struct hostent *hp, int *errp) { struct hostent *nhp; char *cp, **pp; int size, addrsize; int nalias = 0, naddr = 0; int al_off; int i; if (hp == NULL) return hp; /* count size to be allocated */ size = sizeof(struct hostent); if (hp->h_name != NULL) size += strlen(hp->h_name) + 1; if ((pp = hp->h_aliases) != NULL) { for (i = 0; *pp != NULL; i++, pp++) { if (**pp != '\0') { size += strlen(*pp) + 1; nalias++; } } } /* adjust alignment */ size = ALIGN(size); al_off = size; size += sizeof(char *) * (nalias + 1); addrsize = ALIGN(hp->h_length); if ((pp = hp->h_addr_list) != NULL) { while (*pp++ != NULL) naddr++; } size += addrsize * naddr; size += sizeof(char *) * (naddr + 1); /* copy */ if ((nhp = (struct hostent *)malloc(size)) == NULL) { *errp = TRY_AGAIN; return NULL; } cp = (char *)&nhp[1]; if (hp->h_name != NULL) { nhp->h_name = cp; strcpy(cp, hp->h_name); cp += strlen(cp) + 1; } else nhp->h_name = NULL; nhp->h_aliases = (char **)((char *)nhp + al_off); if ((pp = hp->h_aliases) != NULL) { for (i = 0; *pp != NULL; pp++) { if (**pp != '\0') { nhp->h_aliases[i++] = cp; strcpy(cp, *pp); cp += strlen(cp) + 1; } } } nhp->h_aliases[nalias] = NULL; cp = (char *)&nhp->h_aliases[nalias + 1]; nhp->h_addrtype = hp->h_addrtype; nhp->h_length = hp->h_length; nhp->h_addr_list = (char **)cp; if ((pp = hp->h_addr_list) != NULL) { cp = (char *)&nhp->h_addr_list[naddr + 1]; for (i = 0; *pp != NULL; pp++) { nhp->h_addr_list[i++] = cp; memcpy(cp, *pp, hp->h_length); cp += addrsize; } } nhp->h_addr_list[naddr] = NULL; return nhp; } /* * _hpaddr: construct hostent structure with one address */ static struct hostent * _hpaddr(int af, const char *name, void *addr, int *errp) { struct hostent *hp, hpbuf; char *addrs[2]; hp = &hpbuf; hp->h_name = (char *)name; hp->h_aliases = NULL; hp->h_addrtype = af; hp->h_length = ADDRLEN(af); hp->h_addr_list = addrs; addrs[0] = (char *)addr; addrs[1] = NULL; return (_hpcopy(hp, errp)); } #ifdef INET6 /* * _hpmerge: merge 2 hostent structure, arguments will be freed */ static struct hostent * _hpmerge(struct hostent *hp1, struct hostent *hp2, int *errp) { int i, j; int naddr, nalias; char **pp; struct hostent *hp, hpbuf; char *aliases[MAXALIASES + 1], *addrs[MAXADDRS + 1]; union inx_addr addrbuf[MAXADDRS]; if (hp1 == NULL) return _hpcopy(hp2, errp); if (hp2 == NULL) return _hpcopy(hp1, errp); #define HP(i) (i == 1 ? hp1 : hp2) hp = &hpbuf; hp->h_name = (hp1->h_name != NULL ? hp1->h_name : hp2->h_name); hp->h_aliases = aliases; nalias = 0; for (i = 1; i <= 2; i++) { if ((pp = HP(i)->h_aliases) == NULL) continue; for (; nalias < MAXALIASES && *pp != NULL; pp++) { /* check duplicates */ for (j = 0; j < nalias; j++) if (strcasecmp(*pp, aliases[j]) == 0) break; if (j == nalias) aliases[nalias++] = *pp; } } aliases[nalias] = NULL; if (hp1->h_length != hp2->h_length) { hp->h_addrtype = AF_INET6; hp->h_length = sizeof(struct in6_addr); } else { hp->h_addrtype = hp1->h_addrtype; hp->h_length = hp1->h_length; } hp->h_addr_list = addrs; naddr = 0; for (i = 1; i <= 2; i++) { if ((pp = HP(i)->h_addr_list) == NULL) continue; if (HP(i)->h_length == hp->h_length) { while (naddr < MAXADDRS && *pp != NULL) addrs[naddr++] = *pp++; } else { /* copy IPv4 addr as mapped IPv6 addr */ while (naddr < MAXADDRS && *pp != NULL) { MAPADDR(&addrbuf[naddr], *pp++); addrs[naddr] = (char *)&addrbuf[naddr]; naddr++; } } } addrs[naddr] = NULL; return (_hpcopy(hp, errp)); } #endif /* * _hpmapv6: convert IPv4 hostent into IPv4-mapped IPv6 addresses */ #ifdef INET6 static struct hostent * _hpmapv6(struct hostent *hp, int *errp) { struct hostent hp6; if (hp == NULL) return NULL; if (hp->h_addrtype == AF_INET6) return _hpcopy(hp, errp); memset(&hp6, 0, sizeof(struct hostent)); hp6.h_addrtype = AF_INET6; hp6.h_length = sizeof(struct in6_addr); return _hpmerge(&hp6, hp, errp); } #endif /* * _hpsort: sort address by sortlist */ static struct hostent * _hpsort(struct hostent *hp, res_state statp) { int i, j, n; u_char *ap, *sp, *mp, **pp; char t; char order[MAXADDRS]; int nsort = statp->nsort; if (hp == NULL || hp->h_addr_list[1] == NULL || nsort == 0) return hp; for (i = 0; (ap = (u_char *)hp->h_addr_list[i]); i++) { for (j = 0; j < nsort; j++) { #ifdef INET6 if (statp->_u._ext.ext->sort_list[j].af != hp->h_addrtype) continue; sp = (u_char *)&statp->_u._ext.ext->sort_list[j].addr; mp = (u_char *)&statp->_u._ext.ext->sort_list[j].mask; #else sp = (u_char *)&statp->sort_list[j].addr; mp = (u_char *)&statp->sort_list[j].mask; #endif for (n = 0; n < hp->h_length; n++) { if ((ap[n] & mp[n]) != sp[n]) break; } if (n == hp->h_length) break; } order[i] = j; } n = i; pp = (u_char **)hp->h_addr_list; for (i = 0; i < n - 1; i++) { for (j = i + 1; j < n; j++) { if (order[i] > order[j]) { ap = pp[i]; pp[i] = pp[j]; pp[j] = ap; t = order[i]; order[i] = order[j]; order[j] = t; } } } return hp; } #ifdef INET6 /* * _hpreorder: sort address by default address selection */ static struct hostent * _hpreorder(struct hostent *hp) { struct hp_order *aio; int i, n; char *ap; struct sockaddr *sa; struct policyhead policyhead; if (hp == NULL) return hp; switch (hp->h_addrtype) { case AF_INET: #ifdef INET6 case AF_INET6: #endif break; default: free_addrselectpolicy(&policyhead); return hp; } /* count the number of addrinfo elements for sorting. */ for (n = 0; hp->h_addr_list[n] != NULL; n++) ; /* * If the number is small enough, we can skip the reordering process. */ if (n <= 1) return hp; /* allocate a temporary array for sort and initialization of it. */ if ((aio = malloc(sizeof(*aio) * n)) == NULL) return hp; /* give up reordering */ memset(aio, 0, sizeof(*aio) * n); /* retrieve address selection policy from the kernel */ TAILQ_INIT(&policyhead); if (!get_addrselectpolicy(&policyhead)) { /* no policy is installed into kernel, we don't sort. */ free(aio); return hp; } for (i = 0; i < n; i++) { ap = hp->h_addr_list[i]; aio[i].aio_h_addr = ap; sa = &aio[i].aio_sa; switch (hp->h_addrtype) { case AF_INET: sa->sa_family = AF_INET; sa->sa_len = sizeof(struct sockaddr_in); memcpy(&((struct sockaddr_in *)sa)->sin_addr, ap, sizeof(struct in_addr)); break; #ifdef INET6 case AF_INET6: if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)ap)) { sa->sa_family = AF_INET; sa->sa_len = sizeof(struct sockaddr_in); memcpy(&((struct sockaddr_in *)sa)->sin_addr, &ap[12], sizeof(struct in_addr)); } else { sa->sa_family = AF_INET6; sa->sa_len = sizeof(struct sockaddr_in6); memcpy(&((struct sockaddr_in6 *)sa)->sin6_addr, ap, sizeof(struct in6_addr)); } break; #endif } aio[i].aio_dstscope = gai_addr2scopetype(sa); aio[i].aio_dstpolicy = match_addrselectpolicy(sa, &policyhead); set_source(&aio[i], &policyhead); } /* perform sorting. */ qsort(aio, n, sizeof(*aio), comp_dst); /* reorder the h_addr_list. */ for (i = 0; i < n; i++) hp->h_addr_list[i] = aio[i].aio_h_addr; /* cleanup and return */ free(aio); free_addrselectpolicy(&policyhead); return hp; } static int get_addrselectpolicy(struct policyhead *head) { #ifdef INET6 int mib[] = { CTL_NET, PF_INET6, IPPROTO_IPV6, IPV6CTL_ADDRCTLPOLICY }; size_t l; char *buf; struct in6_addrpolicy *pol, *ep; if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), NULL, &l, NULL, 0) < 0) return (0); if ((buf = malloc(l)) == NULL) return (0); if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), buf, &l, NULL, 0) < 0) { free(buf); return (0); } ep = (struct in6_addrpolicy *)(buf + l); for (pol = (struct in6_addrpolicy *)buf; pol + 1 <= ep; pol++) { struct policyqueue *new; if ((new = malloc(sizeof(*new))) == NULL) { free_addrselectpolicy(head); /* make the list empty */ break; } new->pc_policy = *pol; TAILQ_INSERT_TAIL(head, new, pc_entry); } free(buf); return (1); #else return (0); #endif } static void free_addrselectpolicy(struct policyhead *head) { struct policyqueue *ent, *nent; for (ent = TAILQ_FIRST(head); ent; ent = nent) { nent = TAILQ_NEXT(ent, pc_entry); TAILQ_REMOVE(head, ent, pc_entry); free(ent); } } static struct policyqueue * match_addrselectpolicy(struct sockaddr *addr, struct policyhead *head) { #ifdef INET6 struct policyqueue *ent, *bestent = NULL; struct in6_addrpolicy *pol; int matchlen, bestmatchlen = -1; u_char *mp, *ep, *k, *p, m; struct sockaddr_in6 key; switch(addr->sa_family) { case AF_INET6: key = *(struct sockaddr_in6 *)addr; break; case AF_INET: /* convert the address into IPv4-mapped IPv6 address. */ memset(&key, 0, sizeof(key)); key.sin6_family = AF_INET6; key.sin6_len = sizeof(key); - key.sin6_addr.s6_addr[10] = 0xff; - key.sin6_addr.s6_addr[11] = 0xff; - memcpy(&key.sin6_addr.s6_addr[12], - &((struct sockaddr_in *)addr)->sin_addr, 4); + _map_v4v6_address( + (char *)&((struct sockaddr_in *)addr)->sin_addr, + (char *)&key.sin6_addr); break; default: return(NULL); } for (ent = TAILQ_FIRST(head); ent; ent = TAILQ_NEXT(ent, pc_entry)) { pol = &ent->pc_policy; matchlen = 0; mp = (u_char *)&pol->addrmask.sin6_addr; ep = mp + 16; /* XXX: scope field? */ k = (u_char *)&key.sin6_addr; p = (u_char *)&pol->addr.sin6_addr; for (; mp < ep && *mp; mp++, k++, p++) { m = *mp; if ((*k & m) != *p) goto next; /* not match */ if (m == 0xff) /* short cut for a typical case */ matchlen += 8; else { while (m >= 0x80) { matchlen++; m <<= 1; } } } /* matched. check if this is better than the current best. */ if (matchlen > bestmatchlen) { bestent = ent; bestmatchlen = matchlen; } next: continue; } return(bestent); #else return(NULL); #endif } static void set_source(struct hp_order *aio, struct policyhead *ph) { struct sockaddr_storage ss = aio->aio_un.aiou_ss; socklen_t srclen; int s; /* set unspec ("no source is available"), just in case */ aio->aio_srcsa.sa_family = AF_UNSPEC; aio->aio_srcscope = -1; switch(ss.ss_family) { case AF_INET: ((struct sockaddr_in *)&ss)->sin_port = htons(1); break; #ifdef INET6 case AF_INET6: ((struct sockaddr_in6 *)&ss)->sin6_port = htons(1); break; #endif default: /* ignore unsupported AFs explicitly */ return; } /* open a socket to get the source address for the given dst */ if ((s = _socket(ss.ss_family, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_UDP)) < 0) return; /* give up */ if (_connect(s, (struct sockaddr *)&ss, ss.ss_len) < 0) goto cleanup; srclen = ss.ss_len; if (_getsockname(s, &aio->aio_srcsa, &srclen) < 0) { aio->aio_srcsa.sa_family = AF_UNSPEC; goto cleanup; } aio->aio_srcscope = gai_addr2scopetype(&aio->aio_srcsa); aio->aio_srcpolicy = match_addrselectpolicy(&aio->aio_srcsa, ph); aio->aio_matchlen = matchlen(&aio->aio_srcsa, (struct sockaddr *)&ss); #ifdef INET6 if (ss.ss_family == AF_INET6) { struct in6_ifreq ifr6; u_int32_t flags6; memset(&ifr6, 0, sizeof(ifr6)); memcpy(&ifr6.ifr_addr, &ss, ss.ss_len); if (_ioctl(s, SIOCGIFAFLAG_IN6, &ifr6) == 0) { flags6 = ifr6.ifr_ifru.ifru_flags6; if ((flags6 & IN6_IFF_DEPRECATED)) aio->aio_srcflag |= AIO_SRCFLAG_DEPRECATED; } } #endif cleanup: _close(s); return; } static int matchlen(struct sockaddr *src, struct sockaddr *dst) { int match = 0; u_char *s, *d; u_char *lim, r; int addrlen; switch (src->sa_family) { #ifdef INET6 case AF_INET6: s = (u_char *)&((struct sockaddr_in6 *)src)->sin6_addr; d = (u_char *)&((struct sockaddr_in6 *)dst)->sin6_addr; addrlen = sizeof(struct in6_addr); lim = s + addrlen; break; #endif case AF_INET: s = (u_char *)&((struct sockaddr_in *)src)->sin_addr; d = (u_char *)&((struct sockaddr_in *)dst)->sin_addr; addrlen = sizeof(struct in_addr); lim = s + addrlen; break; default: return(0); } while (s < lim) if ((r = (*d++ ^ *s++)) != 0) { while (r < addrlen * 8) { match++; r <<= 1; } break; } else match += 8; return(match); } static int comp_dst(const void *arg1, const void *arg2) { const struct hp_order *dst1 = arg1, *dst2 = arg2; /* * Rule 1: Avoid unusable destinations. * XXX: we currently do not consider if an appropriate route exists. */ if (dst1->aio_srcsa.sa_family != AF_UNSPEC && dst2->aio_srcsa.sa_family == AF_UNSPEC) { return(-1); } if (dst1->aio_srcsa.sa_family == AF_UNSPEC && dst2->aio_srcsa.sa_family != AF_UNSPEC) { return(1); } /* Rule 2: Prefer matching scope. */ if (dst1->aio_dstscope == dst1->aio_srcscope && dst2->aio_dstscope != dst2->aio_srcscope) { return(-1); } if (dst1->aio_dstscope != dst1->aio_srcscope && dst2->aio_dstscope == dst2->aio_srcscope) { return(1); } /* Rule 3: Avoid deprecated addresses. */ if (dst1->aio_srcsa.sa_family != AF_UNSPEC && dst2->aio_srcsa.sa_family != AF_UNSPEC) { if (!(dst1->aio_srcflag & AIO_SRCFLAG_DEPRECATED) && (dst2->aio_srcflag & AIO_SRCFLAG_DEPRECATED)) { return(-1); } if ((dst1->aio_srcflag & AIO_SRCFLAG_DEPRECATED) && !(dst2->aio_srcflag & AIO_SRCFLAG_DEPRECATED)) { return(1); } } /* Rule 4: Prefer home addresses. */ /* XXX: not implemented yet */ /* Rule 5: Prefer matching label. */ #ifdef INET6 if (dst1->aio_srcpolicy && dst1->aio_dstpolicy && dst1->aio_srcpolicy->pc_policy.label == dst1->aio_dstpolicy->pc_policy.label && (dst2->aio_srcpolicy == NULL || dst2->aio_dstpolicy == NULL || dst2->aio_srcpolicy->pc_policy.label != dst2->aio_dstpolicy->pc_policy.label)) { return(-1); } if (dst2->aio_srcpolicy && dst2->aio_dstpolicy && dst2->aio_srcpolicy->pc_policy.label == dst2->aio_dstpolicy->pc_policy.label && (dst1->aio_srcpolicy == NULL || dst1->aio_dstpolicy == NULL || dst1->aio_srcpolicy->pc_policy.label != dst1->aio_dstpolicy->pc_policy.label)) { return(1); } #endif /* Rule 6: Prefer higher precedence. */ #ifdef INET6 if (dst1->aio_dstpolicy && (dst2->aio_dstpolicy == NULL || dst1->aio_dstpolicy->pc_policy.preced > dst2->aio_dstpolicy->pc_policy.preced)) { return(-1); } if (dst2->aio_dstpolicy && (dst1->aio_dstpolicy == NULL || dst2->aio_dstpolicy->pc_policy.preced > dst1->aio_dstpolicy->pc_policy.preced)) { return(1); } #endif /* Rule 7: Prefer native transport. */ /* XXX: not implemented yet */ /* Rule 8: Prefer smaller scope. */ if (dst1->aio_dstscope >= 0 && dst1->aio_dstscope < dst2->aio_dstscope) { return(-1); } if (dst2->aio_dstscope >= 0 && dst2->aio_dstscope < dst1->aio_dstscope) { return(1); } /* * Rule 9: Use longest matching prefix. * We compare the match length in a same AF only. */ if (dst1->aio_sa.sa_family == dst2->aio_sa.sa_family) { if (dst1->aio_matchlen > dst2->aio_matchlen) { return(-1); } if (dst1->aio_matchlen < dst2->aio_matchlen) { return(1); } } /* Rule 10: Otherwise, leave the order unchanged. */ return(-1); } /* * Copy from scope.c. * XXX: we should standardize the functions and link them as standard * library. */ static int gai_addr2scopetype(struct sockaddr *sa) { #ifdef INET6 struct sockaddr_in6 *sa6; #endif struct sockaddr_in *sa4; switch(sa->sa_family) { #ifdef INET6 case AF_INET6: sa6 = (struct sockaddr_in6 *)sa; if (IN6_IS_ADDR_MULTICAST(&sa6->sin6_addr)) { /* just use the scope field of the multicast address */ return(sa6->sin6_addr.s6_addr[2] & 0x0f); } /* * Unicast addresses: map scope type to corresponding scope * value defined for multcast addresses. * XXX: hardcoded scope type values are bad... */ if (IN6_IS_ADDR_LOOPBACK(&sa6->sin6_addr)) return(1); /* node local scope */ if (IN6_IS_ADDR_LINKLOCAL(&sa6->sin6_addr)) return(2); /* link-local scope */ if (IN6_IS_ADDR_SITELOCAL(&sa6->sin6_addr)) return(5); /* site-local scope */ return(14); /* global scope */ break; #endif case AF_INET: /* * IPv4 pseudo scoping according to RFC 3484. */ sa4 = (struct sockaddr_in *)sa; /* IPv4 autoconfiguration addresses have link-local scope. */ if (((u_char *)&sa4->sin_addr)[0] == 169 && ((u_char *)&sa4->sin_addr)[1] == 254) return(2); /* Private addresses have site-local scope. */ if (((u_char *)&sa4->sin_addr)[0] == 10 || (((u_char *)&sa4->sin_addr)[0] == 172 && (((u_char *)&sa4->sin_addr)[1] & 0xf0) == 16) || (((u_char *)&sa4->sin_addr)[0] == 192 && ((u_char *)&sa4->sin_addr)[1] == 168)) return(14); /* XXX: It should be 5 unless NAT */ /* Loopback addresses have link-local scope. */ if (((u_char *)&sa4->sin_addr)[0] == 127) return(2); return(14); break; default: errno = EAFNOSUPPORT; /* is this a good error? */ return(-1); } } #endif Index: user/ngie/stable-10-libnv/lib/libc/sys/clock_gettime.2 =================================================================== --- user/ngie/stable-10-libnv/lib/libc/sys/clock_gettime.2 (revision 292856) +++ user/ngie/stable-10-libnv/lib/libc/sys/clock_gettime.2 (revision 292857) @@ -1,168 +1,164 @@ .\" $OpenBSD: clock_gettime.2,v 1.4 1997/05/08 20:21:16 kstailey Exp $ .\" .\" Copyright (c) 1980, 1991, 1993 .\" The Regents of the University of California. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. .\" .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" .\" $FreeBSD$ .\" -.Dd December 29, 2009 +.Dd December 20, 2015 .Dt CLOCK_GETTIME 2 .Os .Sh NAME .Nm clock_gettime , .Nm clock_settime , .Nm clock_getres .Nd get/set/calibrate date and time .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In time.h .Ft int .Fn clock_gettime "clockid_t clock_id" "struct timespec *tp" .Ft int .Fn clock_settime "clockid_t clock_id" "const struct timespec *tp" .Ft int .Fn clock_getres "clockid_t clock_id" "struct timespec *tp" .Sh DESCRIPTION The .Fn clock_gettime and .Fn clock_settime system calls allow the calling process to retrieve or set the value used by a clock which is specified by .Fa clock_id . .Pp The .Fa clock_id argument can be one of the following values: .Dv CLOCK_REALTIME , .Dv CLOCK_REALTIME_PRECISE , .Dv CLOCK_REALTIME_FAST for time that increments as a wall clock should; .Dv CLOCK_MONOTONIC , .Dv CLOCK_MONOTONIC_PRECISE , .Dv CLOCK_MONOTONIC_FAST which increments in SI seconds; .Dv CLOCK_UPTIME , .Dv CLOCK_UPTIME_PRECISE , .Dv CLOCK_UPTIME_FAST which starts at zero when the kernel boots and increments monotonically in SI seconds while the machine is running; .Dv CLOCK_VIRTUAL for time that increments only when the CPU is running in user mode on behalf of the calling process; .Dv CLOCK_PROF for time that increments when the CPU is running in user or kernel mode; or .Dv CLOCK_SECOND which returns the current second without performing a full time counter query, using in-kernel cached value of current second. .Pp The clock IDs .Fa CLOCK_REALTIME_FAST , .Fa CLOCK_MONOTONIC_FAST , .Fa CLOCK_UPTIME_FAST are analogs of corresponding IDs without _FAST suffix but do not perform a full time counter query, so their accuracy is one timer tick. Similarly, .Fa CLOCK_REALTIME_PRECISE , .Fa CLOCK_MONOTONIC_PRECISE , .Fa CLOCK_UPTIME_PRECISE are used to get the most exact value as possible, at the expense of execution time. .Pp The structure pointed to by .Fa tp is defined in .In sys/timespec.h as: .Bd -literal struct timespec { time_t tv_sec; /* seconds */ long tv_nsec; /* and nanoseconds */ }; .Ed .Pp Only the super-user may set the time of day, using only .Fa CLOCK_REALTIME . If the system securelevel is greater than 1 (see .Xr init 8 ) , the time may only be advanced. This limitation is imposed to prevent a malicious super-user from setting arbitrary time stamps on files. The system time can still be adjusted backwards using the .Xr adjtime 2 system call even when the system is secure. .Pp The resolution (granularity) of a clock is returned by the .Fn clock_getres system call. This value is placed in a (non-NULL) .Fa *tp . .Sh RETURN VALUES .Rv -std .Sh ERRORS The following error codes may be set in .Va errno : .Bl -tag -width Er .It Bq Er EINVAL The .Fa clock_id argument was not a valid value. -.It Bq Er EFAULT -The -.Fa *tp -argument address referenced invalid memory. .It Bq Er EPERM A user other than the super-user attempted to set the time. .El .Sh SEE ALSO .Xr date 1 , .Xr adjtime 2 , .Xr ctime 3 , .Xr timed 8 .Sh STANDARDS The .Fn clock_gettime , .Fn clock_settime , and .Fn clock_getres system calls conform to .St -p1003.1b-93 . The clock IDs .Fa CLOCK_REALTIME_FAST , .Fa CLOCK_REALTIME_PRECISE , .Fa CLOCK_MONOTONIC_FAST , .Fa CLOCK_MONOTONIC_PRECISE , .Fa CLOCK_UPTIME , .Fa CLOCK_UPTIME_FAST , .Fa CLOCK_UPTIME_PRECISE , .Fa CLOCK_SECOND are FreeBSD extensions to the POSIX interface. Index: user/ngie/stable-10-libnv/lib/libc/sys/gettimeofday.2 =================================================================== --- user/ngie/stable-10-libnv/lib/libc/sys/gettimeofday.2 (revision 292856) +++ user/ngie/stable-10-libnv/lib/libc/sys/gettimeofday.2 (revision 292857) @@ -1,130 +1,128 @@ .\" Copyright (c) 1980, 1991, 1993 .\" The Regents of the University of California. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. .\" .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" .\" @(#)gettimeofday.2 8.2 (Berkeley) 5/26/95 .\" $FreeBSD$ .\" -.Dd May 26, 1995 +.Dd December 20, 2015 .Dt GETTIMEOFDAY 2 .Os .Sh NAME .Nm gettimeofday , .Nm settimeofday .Nd get/set date and time .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In sys/time.h .Ft int .Fn gettimeofday "struct timeval *tp" "struct timezone *tzp" .Ft int .Fn settimeofday "const struct timeval *tp" "const struct timezone *tzp" .Sh DESCRIPTION .Bf -symbolic Note: timezone is no longer used; this information is kept outside the kernel. .Ef .Pp The system's notion of the current Greenwich time and the current time zone is obtained with the .Fn gettimeofday system call, and set with the .Fn settimeofday system call. The time is expressed in seconds and microseconds since midnight (0 hour), January 1, 1970. The resolution of the system clock is hardware dependent, and the time may be updated continuously or in .Dq ticks . If .Fa tp or .Fa tzp is NULL, the associated time information will not be returned or set. .Pp The structures pointed to by .Fa tp and .Fa tzp are defined in .In sys/time.h as: .Bd -literal struct timeval { time_t tv_sec; /* seconds */ suseconds_t tv_usec; /* and microseconds */ }; struct timezone { int tz_minuteswest; /* minutes west of Greenwich */ int tz_dsttime; /* type of dst correction */ }; .Ed .Pp The .Vt timezone structure indicates the local time zone (measured in minutes of time westward from Greenwich), and a flag that, if nonzero, indicates that Daylight Saving time applies locally during the appropriate part of the year. .Pp Only the super-user may set the time of day or time zone. If the system is running at securelevel >= 2 (see .Xr init 8 ) , the time may only be advanced or retarded by a maximum of one second. This limitation is imposed to prevent a malicious super-user from setting arbitrary time stamps on files. The system time can be adjusted backwards without restriction using the .Xr adjtime 2 system call even when the system is secure. .Sh RETURN VALUES .Rv -std .Sh ERRORS The following error codes may be set in .Va errno : .Bl -tag -width Er -.It Bq Er EFAULT -An argument address referenced invalid memory. .It Bq Er EPERM A user other than the super-user attempted to set the time. .El .Sh SEE ALSO .Xr date 1 , .Xr adjtime 2 , .Xr clock_gettime 2 , .Xr ctime 3 , .Xr timeradd 3 , .Xr clocks 7 , .Xr timed 8 .Sh HISTORY The .Fn gettimeofday system call appeared in .Bx 4.2 . Index: user/ngie/stable-10-libnv/lib/libc/tests/Makefile =================================================================== --- user/ngie/stable-10-libnv/lib/libc/tests/Makefile (revision 292856) +++ user/ngie/stable-10-libnv/lib/libc/tests/Makefile (revision 292857) @@ -1,33 +1,35 @@ # $FreeBSD$ .include TESTSDIR= ${TESTSBASE}/lib/libc SUBDIR= tls_dso TESTS_SUBDIRS= c063 TESTS_SUBDIRS+= db TESTS_SUBDIRS+= gen TESTS_SUBDIRS+= hash TESTS_SUBDIRS+= inet TESTS_SUBDIRS+= net +TESTS_SUBDIRS+= nss TESTS_SUBDIRS+= regex +TESTS_SUBDIRS+= resolv TESTS_SUBDIRS+= rpc TESTS_SUBDIRS+= stdio TESTS_SUBDIRS+= stdlib TESTS_SUBDIRS+= string TESTS_SUBDIRS+= sys TESTS_SUBDIRS+= termios TESTS_SUBDIRS+= tls TESTS_SUBDIRS+= ttyio .if ${MK_LOCALES} != "no" TESTS_SUBDIRS+= locale .endif .if ${MK_SSP} != "no" TESTS_SUBDIRS+= ssp .endif .include Index: user/ngie/stable-10-libnv/lib/libc/tests/nss/Makefile =================================================================== --- user/ngie/stable-10-libnv/lib/libc/tests/nss/Makefile (nonexistent) +++ user/ngie/stable-10-libnv/lib/libc/tests/nss/Makefile (revision 292857) @@ -0,0 +1,22 @@ +# $FreeBSD$ + +TESTSDIR= ${TESTSBASE}/lib/libc/nss +BINDIR= ${TESTSDIR} + +.PATH: ${.CURDIR:H}/resolv + +FILES+= mach + +CFLAGS+= -I${SRCTOP}/tests + +ATF_TESTS_C+= getaddrinfo_test +ATF_TESTS_C+= getgr_test +ATF_TESTS_C+= gethostby_test +TEST_METADATA.gethostby_test= timeout="1200" +ATF_TESTS_C+= getpw_test +ATF_TESTS_C+= getproto_test +ATF_TESTS_C+= getrpc_test +ATF_TESTS_C+= getserv_test +ATF_TESTS_C+= getusershell_test + +.include Property changes on: user/ngie/stable-10-libnv/lib/libc/tests/nss/Makefile ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: user/ngie/stable-10-libnv/lib/libc/tests/nss/getaddrinfo_test.c =================================================================== --- user/ngie/stable-10-libnv/lib/libc/tests/nss/getaddrinfo_test.c (nonexistent) +++ user/ngie/stable-10-libnv/lib/libc/tests/nss/getaddrinfo_test.c (revision 292857) @@ -0,0 +1,556 @@ +/*- + * Copyright (c) 2006 Michael Bushkov + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "freebsd_test_suite/macros.h" +#include "testutil.h" + +enum test_methods { + TEST_GETADDRINFO, + TEST_BUILD_SNAPSHOT +}; + +static struct addrinfo hints; +static enum test_methods method = TEST_GETADDRINFO; + +DECLARE_TEST_DATA(addrinfo) +DECLARE_TEST_FILE_SNAPSHOT(addrinfo) +DECLARE_2PASS_TEST(addrinfo) + +static void clone_addrinfo(struct addrinfo *, struct addrinfo const *); +static int compare_addrinfo(struct addrinfo *, struct addrinfo *, void *); +static void dump_addrinfo(struct addrinfo *); + +static void sdump_addrinfo(struct addrinfo *, char *, size_t); + +IMPLEMENT_TEST_DATA(addrinfo) +IMPLEMENT_TEST_FILE_SNAPSHOT(addrinfo) +IMPLEMENT_2PASS_TEST(addrinfo) + +static void +clone_addrinfo(struct addrinfo *dest, struct addrinfo const *src) +{ + + ATF_REQUIRE(dest != NULL); + ATF_REQUIRE(src != NULL); + + memcpy(dest, src, sizeof(struct addrinfo)); + if (src->ai_canonname != NULL) + dest->ai_canonname = strdup(src->ai_canonname); + + if (src->ai_addr != NULL) { + dest->ai_addr = malloc(src->ai_addrlen); + ATF_REQUIRE(dest->ai_addr != NULL); + memcpy(dest->ai_addr, src->ai_addr, src->ai_addrlen); + } + + if (src->ai_next != NULL) { + dest->ai_next = malloc(sizeof(struct addrinfo)); + ATF_REQUIRE(dest->ai_next != NULL); + clone_addrinfo(dest->ai_next, src->ai_next); + } +} + +static int +compare_addrinfo_(struct addrinfo *ai1, struct addrinfo *ai2) +{ + + if ((ai1 == NULL) || (ai2 == NULL)) + return (-1); + + if (ai1->ai_flags != ai2->ai_flags || + ai1->ai_family != ai2->ai_family || + ai1->ai_socktype != ai2->ai_socktype || + ai1->ai_protocol != ai2->ai_protocol || + ai1->ai_addrlen != ai2->ai_addrlen || + ((ai1->ai_addr == NULL || ai2->ai_addr == NULL) && + ai1->ai_addr != ai2->ai_addr) || + ((ai1->ai_canonname == NULL || ai2->ai_canonname == NULL) && + ai1->ai_canonname != ai2->ai_canonname)) + return (-1); + + if (ai1->ai_canonname != NULL && + strcmp(ai1->ai_canonname, ai2->ai_canonname) != 0) + return (-1); + + if (ai1->ai_addr != NULL && + memcmp(ai1->ai_addr, ai2->ai_addr, ai1->ai_addrlen) != 0) + return (-1); + + if (ai1->ai_next == NULL && ai2->ai_next == NULL) + return (0); + else + return (compare_addrinfo_(ai1->ai_next, ai2->ai_next)); +} + +static int +compare_addrinfo(struct addrinfo *ai1, struct addrinfo *ai2, void *mdata) +{ + int rv; + + printf("testing equality of 2 addrinfo structures\n"); + + rv = compare_addrinfo_(ai1, ai2); + + if (rv == 0) + printf("equal\n"); + else { + dump_addrinfo(ai1); + dump_addrinfo(ai2); + printf("not equal\n"); + } + + return (rv); +} + +void +free_addrinfo(struct addrinfo *ai) +{ + if (ai == NULL) + return; + + free(ai->ai_addr); + free(ai->ai_canonname); + free_addrinfo(ai->ai_next); +} + +void +sdump_addrinfo(struct addrinfo *ai, char *buffer, size_t buflen) +{ + int written, i; + + written = snprintf(buffer, buflen, "%d %d %d %d %d ", + ai->ai_flags, ai->ai_family, ai->ai_socktype, ai->ai_protocol, + ai->ai_addrlen); + buffer += written; + if (written > buflen) + return; + buflen -= written; + + written = snprintf(buffer, buflen, "%s ", + ai->ai_canonname == NULL ? "(null)" : ai->ai_canonname); + buffer += written; + if (written > buflen) + return; + buflen -= written; + + if (ai->ai_addr == NULL) { + written = snprintf(buffer, buflen, "(null)"); + buffer += written; + if (written > buflen) + return; + buflen -= written; + } else { + for (i = 0; i < ai->ai_addrlen; i++) { + written = snprintf(buffer, buflen, + i + 1 != ai->ai_addrlen ? "%d." : "%d", + ((unsigned char *)ai->ai_addr)[i]); + buffer += written; + if (written > buflen) + return; + buflen -= written; + + if (buflen == 0) + return; + } + } + + if (ai->ai_next != NULL) { + written = snprintf(buffer, buflen, ":"); + buffer += written; + if (written > buflen) + return; + buflen -= written; + + sdump_addrinfo(ai->ai_next, buffer, buflen); + } +} + +void +dump_addrinfo(struct addrinfo *result) +{ + if (result != NULL) { + char buffer[2048]; + sdump_addrinfo(result, buffer, sizeof(buffer)); + printf("%s\n", buffer); + } else + printf("(null)\n"); +} + +static int +addrinfo_read_snapshot_addr(char *addr, unsigned char *result, size_t len) +{ + char *s, *ps, *ts; + + ps = addr; + while ((s = strsep(&ps, ".")) != NULL) { + if (len == 0) + return (-1); + + *result = (unsigned char)strtol(s, &ts, 10); + ++result; + if (*ts != '\0') + return (-1); + + --len; + } + if (len != 0) + return (-1); + else + return (0); +} + +static int +addrinfo_read_snapshot_ai(struct addrinfo *ai, char *line) +{ + char *s, *ps, *ts; + int i, rv, *pi; + + rv = 0; + i = 0; + ps = line; + memset(ai, 0, sizeof(struct addrinfo)); + while ((s = strsep(&ps, " ")) != NULL) { + switch (i) { + case 0: + case 1: + case 2: + case 3: + pi = &ai->ai_flags + i; + *pi = (int)strtol(s, &ts, 10); + if (*ts != '\0') + goto fin; + break; + case 4: + ai->ai_addrlen = (socklen_t)strtol(s, &ts, 10); + if (*ts != '\0') + goto fin; + break; + case 5: + if (strcmp(s, "(null)") != 0) { + ai->ai_canonname = strdup(s); + ATF_REQUIRE(ai->ai_canonname != NULL); + } + break; + case 6: + if (strcmp(s, "(null)") != 0) { + ai->ai_addr = calloc(1, ai->ai_addrlen); + ATF_REQUIRE(ai->ai_addr != NULL); + rv = addrinfo_read_snapshot_addr(s, + (unsigned char *)ai->ai_addr, + ai->ai_addrlen); + + if (rv != 0) + goto fin; + } + break; + default: + /* NOTE: should not be reachable */ + rv = -1; + goto fin; + } + + ++i; + } + +fin: + if (i != 7 || rv != 0) { + free_addrinfo(ai); + ai = NULL; + return (-1); + } + + return (0); +} + +static int +addrinfo_read_snapshot_func(struct addrinfo *ai, char *line) +{ + struct addrinfo *ai2; + char *s, *ps; + int i, rv; + + printf("1 line read from snapshot:\n%s\n", line); + + rv = 0; + i = 0; + ps = line; + + s = strsep(&ps, ":"); + if (s == NULL) + return (-1); + + rv = addrinfo_read_snapshot_ai(ai, s); + if (rv != 0) + return (-1); + + ai2 = ai; + while ((s = strsep(&ps, ":")) != NULL) { + ai2->ai_next = calloc(1, sizeof(struct addrinfo)); + ATF_REQUIRE(ai2->ai_next != NULL); + + rv = addrinfo_read_snapshot_ai(ai2->ai_next, s); + if (rv != 0) { + free_addrinfo(ai); + ai = NULL; + return (-1); + } + + ai2 = ai2->ai_next; + } + + return (0); +} + +static int +addrinfo_test_correctness(struct addrinfo *ai, void *mdata) +{ + + printf("testing correctness with the following data:\n"); + dump_addrinfo(ai); + + if (ai == NULL) + goto errfin; + + if (!(ai->ai_family >= 0 && ai->ai_family < AF_MAX)) + goto errfin; + + if (ai->ai_socktype != 0 && ai->ai_socktype != SOCK_STREAM && + ai->ai_socktype != SOCK_DGRAM && ai->ai_socktype != SOCK_RAW) + goto errfin; + + if (ai->ai_protocol != 0 && ai->ai_protocol != IPPROTO_UDP && + ai->ai_protocol != IPPROTO_TCP) + goto errfin; + + if ((ai->ai_flags & ~(AI_CANONNAME | AI_NUMERICHOST | AI_PASSIVE)) != 0) + goto errfin; + + if (ai->ai_addrlen != ai->ai_addr->sa_len || + ai->ai_family != ai->ai_addr->sa_family) + goto errfin; + + printf("correct\n"); + + return (0); +errfin: + printf("incorrect\n"); + + return (-1); +} + +static int +addrinfo_read_hostlist_func(struct addrinfo *ai, char *line) +{ + struct addrinfo *result; + int rv; + + printf("resolving %s: ", line); + rv = getaddrinfo(line, NULL, &hints, &result); + if (rv == 0) { + printf("found\n"); + + rv = addrinfo_test_correctness(result, NULL); + if (rv != 0) { + freeaddrinfo(result); + result = NULL; + return (rv); + } + + clone_addrinfo(ai, result); + freeaddrinfo(result); + result = NULL; + } else { + printf("not found\n"); + + memset(ai, 0, sizeof(struct addrinfo)); + } + return (0); +} + +void +run_tests(char *hostlist_file, char *snapshot_file, int ai_family) +{ + struct addrinfo_test_data td, td_snap; + int rv; + + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = ai_family; + hints.ai_flags = AI_CANONNAME; + + if (snapshot_file != NULL) + method = TEST_BUILD_SNAPSHOT; + + TEST_DATA_INIT(addrinfo, &td, clone_addrinfo, free_addrinfo); + TEST_DATA_INIT(addrinfo, &td_snap, clone_addrinfo, free_addrinfo); + + ATF_REQUIRE_MSG(access(hostlist_file, R_OK) == 0, + "can't access the hostlist file %s\n", hostlist_file); + + printf("building host lists from %s\n", hostlist_file); + + rv = TEST_SNAPSHOT_FILE_READ(addrinfo, hostlist_file, &td, + addrinfo_read_hostlist_func); + if (rv != 0) + goto fin; + + if (snapshot_file != NULL) { + if (access(snapshot_file, W_OK | R_OK) != 0) { + if (errno == ENOENT) + method = TEST_BUILD_SNAPSHOT; + else { + printf("can't access the snapshot " + "file %s\n", snapshot_file); + + rv = -1; + goto fin; + } + } else { + rv = TEST_SNAPSHOT_FILE_READ(addrinfo, snapshot_file, + &td_snap, addrinfo_read_snapshot_func); + if (rv != 0) { + printf("error reading snapshot file: %s\n", + strerror(errno)); + goto fin; + } + } + } + + switch (method) { + case TEST_GETADDRINFO: + if (snapshot_file != NULL) + ATF_CHECK(DO_2PASS_TEST(addrinfo, &td, &td_snap, + compare_addrinfo, NULL) == 0); + break; + case TEST_BUILD_SNAPSHOT: + if (snapshot_file != NULL) { + ATF_CHECK(TEST_SNAPSHOT_FILE_WRITE(addrinfo, + snapshot_file, &td, sdump_addrinfo) == 0); + } + break; + default: + break; + } + +fin: + TEST_DATA_DESTROY(addrinfo, &td_snap); + TEST_DATA_DESTROY(addrinfo, &td); + + free(hostlist_file); + free(snapshot_file); +} + +#define HOSTLIST_FILE "mach" +#define RUN_TESTS(tc, snapshot_file, ai_family) do { \ + char *_hostlist_file; \ + char *_snapshot_file; \ + ATF_REQUIRE(0 < asprintf(&_hostlist_file, "%s/%s", \ + atf_tc_get_config_var(tc, "srcdir"), HOSTLIST_FILE)); \ + if (snapshot_file == NULL) \ + _snapshot_file = NULL; \ + else { \ + _snapshot_file = strdup(snapshot_file); \ + ATF_REQUIRE(_snapshot_file != NULL); \ + } \ + run_tests(_hostlist_file, _snapshot_file, ai_family); \ +} while(0) + +ATF_TC_WITHOUT_HEAD(pf_unspec); +ATF_TC_BODY(pf_unspec, tc) +{ + + RUN_TESTS(tc, NULL, AF_UNSPEC); +} + +ATF_TC_WITHOUT_HEAD(pf_unspec_with_snapshot); +ATF_TC_BODY(pf_unspec_with_snapshot, tc) +{ + + RUN_TESTS(tc, "snapshot_ai", AF_UNSPEC); +} + +ATF_TC_WITHOUT_HEAD(pf_inet); +ATF_TC_BODY(pf_inet, tc) +{ + + ATF_REQUIRE_FEATURE("inet"); + RUN_TESTS(tc, NULL, AF_INET); +} + +ATF_TC_WITHOUT_HEAD(pf_inet_with_snapshot); +ATF_TC_BODY(pf_inet_with_snapshot, tc) +{ + + ATF_REQUIRE_FEATURE("inet"); + RUN_TESTS(tc, "snapshot_ai4", AF_INET); +} + +ATF_TC_WITHOUT_HEAD(pf_inet6); +ATF_TC_BODY(pf_inet6, tc) +{ + + ATF_REQUIRE_FEATURE("inet6"); + RUN_TESTS(tc, NULL, AF_INET6); +} + +ATF_TC_WITHOUT_HEAD(pf_inet6_with_snapshot); +ATF_TC_BODY(pf_inet6_with_snapshot, tc) +{ + + ATF_REQUIRE_FEATURE("inet6"); + RUN_TESTS(tc, "snapshot_ai6", AF_INET6); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, pf_unspec); + ATF_TP_ADD_TC(tp, pf_unspec_with_snapshot); + ATF_TP_ADD_TC(tp, pf_inet); + ATF_TP_ADD_TC(tp, pf_inet_with_snapshot); + ATF_TP_ADD_TC(tp, pf_inet6); + ATF_TP_ADD_TC(tp, pf_inet6_with_snapshot); + + return (atf_no_error()); +} Property changes on: user/ngie/stable-10-libnv/lib/libc/tests/nss/getaddrinfo_test.c ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: user/ngie/stable-10-libnv/lib/libc/tests/nss/getgr_test.c =================================================================== --- user/ngie/stable-10-libnv/lib/libc/tests/nss/getgr_test.c (nonexistent) +++ user/ngie/stable-10-libnv/lib/libc/tests/nss/getgr_test.c (revision 292857) @@ -0,0 +1,541 @@ +/*- + * Copyright (c) 2006 Michael Bushkov + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "testutil.h" + +enum test_methods { + TEST_GETGRENT = 1, + TEST_GETGRNAM = 2, + TEST_GETGRGID = 4, + TEST_GETGRENT_2PASS = 8, + TEST_BUILD_SNAPSHOT = 16, +}; + +static enum test_methods method = TEST_BUILD_SNAPSHOT; + +DECLARE_TEST_DATA(group) +DECLARE_TEST_FILE_SNAPSHOT(group) +DECLARE_1PASS_TEST(group) +DECLARE_2PASS_TEST(group) + +static void clone_group(struct group *, struct group const *); +static int compare_group(struct group *, struct group *, void *); +static void dump_group(struct group *); +static void free_group(struct group *); + +static void sdump_group(struct group *, char *, size_t); +static int group_read_snapshot_func(struct group *, char *); + +static int group_check_ambiguity(struct group_test_data *, + struct group *); +static int group_fill_test_data(struct group_test_data *); +static int group_test_correctness(struct group *, void *); +static int group_test_getgrnam(struct group *, void *); +static int group_test_getgrgid(struct group *, void *); +static int group_test_getgrent(struct group *, void *); + +IMPLEMENT_TEST_DATA(group) +IMPLEMENT_TEST_FILE_SNAPSHOT(group) +IMPLEMENT_1PASS_TEST(group) +IMPLEMENT_2PASS_TEST(group) + +static void +clone_group(struct group *dest, struct group const *src) +{ + ATF_REQUIRE(dest != NULL); + ATF_REQUIRE(src != NULL); + + char **cp; + int members_num; + + memset(dest, 0, sizeof(struct group)); + + if (src->gr_name != NULL) { + dest->gr_name = strdup(src->gr_name); + ATF_REQUIRE(dest->gr_name != NULL); + } + + if (src->gr_passwd != NULL) { + dest->gr_passwd = strdup(src->gr_passwd); + ATF_REQUIRE(dest->gr_passwd != NULL); + } + dest->gr_gid = src->gr_gid; + + if (src->gr_mem != NULL) { + members_num = 0; + for (cp = src->gr_mem; *cp; ++cp) + ++members_num; + + dest->gr_mem = calloc(1, (members_num + 1) * sizeof(char *)); + ATF_REQUIRE(dest->gr_mem != NULL); + + for (cp = src->gr_mem; *cp; ++cp) { + dest->gr_mem[cp - src->gr_mem] = strdup(*cp); + ATF_REQUIRE(dest->gr_mem[cp - src->gr_mem] != NULL); + } + } +} + +static void +free_group(struct group *grp) +{ + char **cp; + + ATF_REQUIRE(grp != NULL); + + free(grp->gr_name); + free(grp->gr_passwd); + + for (cp = grp->gr_mem; *cp; ++cp) + free(*cp); + free(grp->gr_mem); +} + +static int +compare_group(struct group *grp1, struct group *grp2, void *mdata) +{ + char **c1, **c2; + + if (grp1 == grp2) + return (0); + + if (grp1 == NULL || grp2 == NULL) + goto errfin; + + if (strcmp(grp1->gr_name, grp2->gr_name) != 0 || + strcmp(grp1->gr_passwd, grp2->gr_passwd) != 0 || + grp1->gr_gid != grp2->gr_gid) + goto errfin; + + c1 = grp1->gr_mem; + c2 = grp2->gr_mem; + + if (grp1->gr_mem == NULL || grp2->gr_mem == NULL) + goto errfin; + + for (; *c1 && *c2; ++c1, ++c2) + if (strcmp(*c1, *c2) != 0) + goto errfin; + + if (*c1 != '\0' || *c2 != '\0') + goto errfin; + + return 0; + +errfin: + if (mdata == NULL) { + printf("following structures are not equal:\n"); + dump_group(grp1); + dump_group(grp2); + } + + return (-1); +} + +static void +sdump_group(struct group *grp, char *buffer, size_t buflen) +{ + char **cp; + int written; + + written = snprintf(buffer, buflen, "%s %s %d", + grp->gr_name, grp->gr_passwd, grp->gr_gid); + buffer += written; + if (written > buflen) + return; + buflen -= written; + + if (grp->gr_mem != NULL) { + if (*(grp->gr_mem) != '\0') { + for (cp = grp->gr_mem; *cp; ++cp) { + written = snprintf(buffer, buflen, " %s",*cp); + buffer += written; + if (written > buflen) + return; + buflen -= written; + + if (buflen == 0) + return; + } + } else + snprintf(buffer, buflen, " nomem"); + } else + snprintf(buffer, buflen, " (null)"); +} + +static int +group_read_snapshot_func(struct group *grp, char *line) +{ + StringList *sl; + char *s, *ps, *ts; + int i; + + printf("1 line read from snapshot:\n%s\n", line); + + i = 0; + sl = NULL; + ps = line; + memset(grp, 0, sizeof(struct group)); + while ((s = strsep(&ps, " ")) != NULL) { + switch (i) { + case 0: + grp->gr_name = strdup(s); + ATF_REQUIRE(grp->gr_name != NULL); + break; + + case 1: + grp->gr_passwd = strdup(s); + ATF_REQUIRE(grp->gr_passwd != NULL); + break; + + case 2: + grp->gr_gid = (gid_t)strtol(s, &ts, 10); + if (*ts != '\0') { + free(grp->gr_name); + free(grp->gr_passwd); + grp->gr_name = NULL; + grp->gr_passwd = NULL; + return (-1); + } + break; + + default: + if (sl == NULL) { + if (strcmp(s, "(null)") == 0) + return (0); + + sl = sl_init(); + ATF_REQUIRE(sl != NULL); + + if (strcmp(s, "nomem") != 0) { + ts = strdup(s); + ATF_REQUIRE(ts != NULL); + sl_add(sl, ts); + } + } else { + ts = strdup(s); + ATF_REQUIRE(ts != NULL); + sl_add(sl, ts); + } + break; + } + ++i; + } + + if (i < 3) { + free(grp->gr_name); + free(grp->gr_passwd); + memset(grp, 0, sizeof(struct group)); + return (-1); + } + + sl_add(sl, NULL); + grp->gr_mem = sl->sl_str; + + /* NOTE: is it a dirty hack or not? */ + free(sl); + return (0); +} + +static void +dump_group(struct group *result) +{ + if (result != NULL) { + char buffer[1024]; + sdump_group(result, buffer, sizeof(buffer)); + printf("%s\n", buffer); + } else + printf("(null)\n"); +} + +static int +group_fill_test_data(struct group_test_data *td) +{ + struct group *grp; + + setgroupent(1); + while ((grp = getgrent()) != NULL) { + if (group_test_correctness(grp, NULL) == 0) + TEST_DATA_APPEND(group, td, grp); + else + return (-1); + } + endgrent(); + + return (0); +} + +static int +group_test_correctness(struct group *grp, void *mdata) +{ + printf("testing correctness with the following data:\n"); + dump_group(grp); + + if (grp == NULL) + goto errfin; + + if (grp->gr_name == NULL) + goto errfin; + + if (grp->gr_passwd == NULL) + goto errfin; + + if (grp->gr_mem == NULL) + goto errfin; + + printf("correct\n"); + + return (0); +errfin: + printf("incorrect\n"); + + return (-1); +} + +/* group_check_ambiguity() is needed here because when doing the getgrent() + * calls sequence, records from different nsswitch sources can be different, + * though having the same pw_name/pw_uid */ +static int +group_check_ambiguity(struct group_test_data *td, struct group *pwd) +{ + + return (TEST_DATA_FIND(group, td, pwd, compare_group, + NULL) != NULL ? 0 : -1); +} + +static int +group_test_getgrnam(struct group *grp_model, void *mdata) +{ + struct group *grp; + + printf("testing getgrnam() with the following data:\n"); + dump_group(grp_model); + + grp = getgrnam(grp_model->gr_name); + if (group_test_correctness(grp, NULL) != 0) + goto errfin; + + if (compare_group(grp, grp_model, NULL) != 0 && + group_check_ambiguity((struct group_test_data *)mdata, grp) != 0) + goto errfin; + + return (0); + +errfin: + return (-1); +} + +static int +group_test_getgrgid(struct group *grp_model, void *mdata) +{ + struct group *grp; + + printf("testing getgrgid() with the following data...\n"); + dump_group(grp_model); + + grp = getgrgid(grp_model->gr_gid); + if (group_test_correctness(grp, NULL) != 0 || + (compare_group(grp, grp_model, NULL) != 0 && + group_check_ambiguity((struct group_test_data *)mdata, grp) != 0)) { + return (-1); + } else { + return (0); + } +} + +static int +group_test_getgrent(struct group *grp, void *mdata) +{ + /* Only correctness can be checked when doing 1-pass test for + * getgrent(). */ + return (group_test_correctness(grp, NULL)); +} + +static int +run_tests(const char *snapshot_file, enum test_methods method) +{ + struct group_test_data td, td_snap, td_2pass; + int rv; + + TEST_DATA_INIT(group, &td, clone_group, free_group); + TEST_DATA_INIT(group, &td_snap, clone_group, free_group); + if (snapshot_file != NULL) { + if (access(snapshot_file, W_OK | R_OK) != 0) { + if (errno == ENOENT) + method = TEST_BUILD_SNAPSHOT; + else { + printf("can't access the file %s\n", + snapshot_file); + + rv = -1; + goto fin; + } + } else { + if (method == TEST_BUILD_SNAPSHOT) { + rv = 0; + goto fin; + } + + TEST_SNAPSHOT_FILE_READ(group, snapshot_file, + &td_snap, group_read_snapshot_func); + } + } + + rv = group_fill_test_data(&td); + if (rv == -1) + return (-1); + switch (method) { + case TEST_GETGRNAM: + if (snapshot_file == NULL) + rv = DO_1PASS_TEST(group, &td, + group_test_getgrnam, (void *)&td); + else + rv = DO_1PASS_TEST(group, &td_snap, + group_test_getgrnam, (void *)&td_snap); + break; + case TEST_GETGRGID: + if (snapshot_file == NULL) + rv = DO_1PASS_TEST(group, &td, + group_test_getgrgid, (void *)&td); + else + rv = DO_1PASS_TEST(group, &td_snap, + group_test_getgrgid, (void *)&td_snap); + break; + case TEST_GETGRENT: + if (snapshot_file == NULL) + rv = DO_1PASS_TEST(group, &td, group_test_getgrent, + (void *)&td); + else + rv = DO_2PASS_TEST(group, &td, &td_snap, + compare_group, NULL); + break; + case TEST_GETGRENT_2PASS: + TEST_DATA_INIT(group, &td_2pass, clone_group, free_group); + rv = group_fill_test_data(&td_2pass); + if (rv != -1) + rv = DO_2PASS_TEST(group, &td, &td_2pass, + compare_group, NULL); + TEST_DATA_DESTROY(group, &td_2pass); + break; + case TEST_BUILD_SNAPSHOT: + if (snapshot_file != NULL) + rv = TEST_SNAPSHOT_FILE_WRITE(group, snapshot_file, &td, + sdump_group); + break; + default: + rv = 0; + break; + } + +fin: + TEST_DATA_DESTROY(group, &td_snap); + TEST_DATA_DESTROY(group, &td); + + return (rv); +} + +#define SNAPSHOT_FILE "snapshot_grp" + +ATF_TC_BODY(getgrent, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETGRENT) == 0); +} + +ATF_TC_WITHOUT_HEAD(getgrent_with_snapshot); +ATF_TC_BODY(getgrent_with_snapshot, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETGRENT) == 0); +} + +ATF_TC_WITHOUT_HEAD(getgrent_with_two_pass); +ATF_TC_BODY(getgrent_with_two_pass, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETGRENT_2PASS) == 0); +} + +ATF_TC_WITHOUT_HEAD(getgrgid); +ATF_TC_BODY(getgrgid, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETGRGID) == 0); +} + +ATF_TC_WITHOUT_HEAD(getgrgid_with_snapshot); +ATF_TC_BODY(getgrgid_with_snapshot, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETGRGID) == 0); +} + +ATF_TC_WITHOUT_HEAD(getgrnam); +ATF_TC_BODY(getgrnam, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETGRNAM) == 0); +} + +ATF_TC_WITHOUT_HEAD(getgrnam_with_snapshot); +ATF_TC_BODY(getgrnam_with_snapshot, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETGRNAM) == 0); +} + +ATF_TC_WITHOUT_HEAD(getgrent); +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, getgrent); + ATF_TP_ADD_TC(tp, getgrent_with_snapshot); + ATF_TP_ADD_TC(tp, getgrent_with_two_pass); + ATF_TP_ADD_TC(tp, getgrgid); + ATF_TP_ADD_TC(tp, getgrgid_with_snapshot); + ATF_TP_ADD_TC(tp, getgrnam); + ATF_TP_ADD_TC(tp, getgrnam_with_snapshot); + + return (atf_no_error()); +} Property changes on: user/ngie/stable-10-libnv/lib/libc/tests/nss/getgr_test.c ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: user/ngie/stable-10-libnv/lib/libc/tests/nss/gethostby_test.c =================================================================== --- user/ngie/stable-10-libnv/lib/libc/tests/nss/gethostby_test.c (nonexistent) +++ user/ngie/stable-10-libnv/lib/libc/tests/nss/gethostby_test.c (revision 292857) @@ -0,0 +1,1506 @@ +/*- + * Copyright (c) 2006 Michael Bushkov + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "freebsd_test_suite/macros.h" +#include "testutil.h" + +enum test_methods { + TEST_GETHOSTBYNAME2, + TEST_GETHOSTBYADDR, + TEST_GETHOSTBYNAME2_GETADDRINFO, + TEST_GETHOSTBYADDR_GETNAMEINFO, + TEST_BUILD_SNAPSHOT, + TEST_BUILD_ADDR_SNAPSHOT +}; + +static int ipnode_flags = 0; +static int af_type = AF_INET; +static bool use_ipnode_functions; + +DECLARE_TEST_DATA(hostent) +DECLARE_TEST_FILE_SNAPSHOT(hostent) +DECLARE_1PASS_TEST(hostent) +DECLARE_2PASS_TEST(hostent) + +/* These stubs will use gethostby***() or getipnodeby***() functions, + * depending on the use_ipnode_functions global variable value */ +static struct hostent *__gethostbyname2(const char *, int); +static struct hostent *__gethostbyaddr(const void *, socklen_t, int); +static void __freehostent(struct hostent *); + +static void clone_hostent(struct hostent *, struct hostent const *); +static int compare_hostent(struct hostent *, struct hostent *, void *); +static void dump_hostent(struct hostent *); +static void free_hostent(struct hostent *); + +static int is_hostent_equal(struct hostent *, struct addrinfo *); + +static void sdump_hostent(struct hostent *, char *, size_t); +static int hostent_read_hostlist_func(struct hostent *, char *); +static int hostent_read_snapshot_addr(char *, unsigned char *, size_t); +static int hostent_read_snapshot_func(struct hostent *, char *); + +static int hostent_test_correctness(struct hostent *, void *); +static int hostent_test_gethostbyaddr(struct hostent *, void *); +static int hostent_test_getaddrinfo_eq(struct hostent *, void *); +static int hostent_test_getnameinfo_eq(struct hostent *, void *); + +static void usage(void) __attribute__((__noreturn__)); + +IMPLEMENT_TEST_DATA(hostent) +IMPLEMENT_TEST_FILE_SNAPSHOT(hostent) +IMPLEMENT_1PASS_TEST(hostent) +IMPLEMENT_2PASS_TEST(hostent) + +static struct hostent * +__gethostbyname2(const char *name, int af) +{ + struct hostent *he; + int error; + + if (use_ipnode_functions) { + error = 0; + he = getipnodebyname(name, af, ipnode_flags, &error); + if (he == NULL) + errno = error; + } else + he = gethostbyname2(name, af); + + return (he); +} + +static struct hostent * +__gethostbyaddr(const void *addr, socklen_t len, int af) +{ + struct hostent *he; + int error; + + if (use_ipnode_functions) { + error = 0; + he = getipnodebyaddr(addr, len, af, &error); + if (he == NULL) + errno = error; + } else + he = gethostbyaddr(addr, len, af); + + return (he); +} + +static void +__freehostent(struct hostent *he) +{ + + /* NOTE: checking for he != NULL - just in case */ + if (use_ipnode_functions && he != NULL) + freehostent(he); +} + +static void +clone_hostent(struct hostent *dest, struct hostent const *src) +{ + ATF_REQUIRE(dest != NULL); + ATF_REQUIRE(src != NULL); + + char **cp; + int aliases_num; + int addrs_num; + size_t offset; + + memset(dest, 0, sizeof(struct hostent)); + + if (src->h_name != NULL) { + dest->h_name = strdup(src->h_name); + ATF_REQUIRE(dest->h_name != NULL); + } + + dest->h_addrtype = src->h_addrtype; + dest->h_length = src->h_length; + + if (src->h_aliases != NULL) { + aliases_num = 0; + for (cp = src->h_aliases; *cp; ++cp) + ++aliases_num; + + dest->h_aliases = calloc(1, (aliases_num + 1) * + sizeof(char *)); + ATF_REQUIRE(dest->h_aliases != NULL); + + for (cp = src->h_aliases; *cp; ++cp) { + dest->h_aliases[cp - src->h_aliases] = strdup(*cp); + ATF_REQUIRE(dest->h_aliases[cp - src->h_aliases] != NULL); + } + } + + if (src->h_addr_list != NULL) { + addrs_num = 0; + for (cp = src->h_addr_list; *cp; ++cp) + ++addrs_num; + + dest->h_addr_list = calloc(1, (addrs_num + 1) * sizeof(char *)); + ATF_REQUIRE(dest->h_addr_list != NULL); + + for (cp = src->h_addr_list; *cp; ++cp) { + offset = cp - src->h_addr_list; + dest->h_addr_list[offset] = malloc(src->h_length); + ATF_REQUIRE(dest->h_addr_list[offset] != NULL); + memcpy(dest->h_addr_list[offset], + src->h_addr_list[offset], src->h_length); + } + } +} + +static void +free_hostent(struct hostent *ht) +{ + char **cp; + + ATF_REQUIRE(ht != NULL); + + free(ht->h_name); + + if (ht->h_aliases != NULL) { + for (cp = ht->h_aliases; *cp; ++cp) + free(*cp); + free(ht->h_aliases); + } + + if (ht->h_addr_list != NULL) { + for (cp = ht->h_addr_list; *cp; ++cp) + free(*cp); + free(ht->h_addr_list); + } +} + +static int +compare_hostent(struct hostent *ht1, struct hostent *ht2, void *mdata) +{ + char **c1, **c2, **ct, **cb; + int b; + + if (ht1 == ht2) + return 0; + + if (ht1 == NULL || ht2 == NULL) + goto errfin; + + if (ht1->h_name == NULL || ht2->h_name == NULL) + goto errfin; + + if (ht1->h_addrtype != ht2->h_addrtype || + ht1->h_length != ht2->h_length || + strcmp(ht1->h_name, ht2->h_name) != 0) + goto errfin; + + c1 = ht1->h_aliases; + c2 = ht2->h_aliases; + + if ((ht1->h_aliases == NULL || ht2->h_aliases == NULL) && + ht1->h_aliases != ht2->h_aliases) + goto errfin; + + if (c1 != NULL && c2 != NULL) { + cb = c1; + for (;*c1; ++c1) { + b = 0; + for (ct = c2; *ct; ++ct) { + if (strcmp(*c1, *ct) == 0) { + b = 1; + break; + } + } + if (b == 0) { + printf("h1 aliases item can't be found in h2 " + "aliases\n"); + goto errfin; + } + } + + c1 = cb; + for (;*c2; ++c2) { + b = 0; + for (ct = c1; *ct; ++ct) { + if (strcmp(*c2, *ct) == 0) { + b = 1; + break; + } + } + if (b == 0) { + printf("h2 aliases item can't be found in h1 " + "aliases\n"); + goto errfin; + } + } + } + + c1 = ht1->h_addr_list; + c2 = ht2->h_addr_list; + + if ((ht1->h_addr_list == NULL || ht2->h_addr_list== NULL) && + ht1->h_addr_list != ht2->h_addr_list) + goto errfin; + + if (c1 != NULL && c2 != NULL) { + cb = c1; + for (; *c1; ++c1) { + b = 0; + for (ct = c2; *ct; ++ct) { + if (memcmp(*c1, *ct, ht1->h_length) == 0) { + b = 1; + break; + } + } + if (b == 0) { + printf("h1 addresses item can't be found in " + "h2 addresses\n"); + goto errfin; + } + } + + c1 = cb; + for (; *c2; ++c2) { + b = 0; + for (ct = c1; *ct; ++ct) { + if (memcmp(*c2, *ct, ht1->h_length) == 0) { + b = 1; + break; + } + } + if (b == 0) { + printf("h2 addresses item can't be found in " + "h1 addresses\n"); + goto errfin; + } + } + } + + return 0; + +errfin: + if (mdata == NULL) { + printf("following structures are not equal:\n"); + dump_hostent(ht1); + dump_hostent(ht2); + } + + return (-1); +} + +static int +check_addrinfo_for_name(struct addrinfo *ai, char const *name) +{ + struct addrinfo *ai2; + + for (ai2 = ai; ai2 != NULL; ai2 = ai2->ai_next) { + if (strcmp(ai2->ai_canonname, name) == 0) + return (0); + } + + return (-1); +} + +static int +check_addrinfo_for_addr(struct addrinfo *ai, char const *addr, + socklen_t addrlen, int af) +{ + struct addrinfo *ai2; + + for (ai2 = ai; ai2 != NULL; ai2 = ai2->ai_next) { + if (af != ai2->ai_family) + continue; + + switch (af) { + case AF_INET: + if (memcmp(addr, + (void *)&((struct sockaddr_in *)ai2->ai_addr)->sin_addr, + MIN(addrlen, ai2->ai_addrlen)) == 0) + return (0); + break; + case AF_INET6: + if (memcmp(addr, + (void *)&((struct sockaddr_in6 *)ai2->ai_addr)->sin6_addr, + MIN(addrlen, ai2->ai_addrlen)) == 0) + return (0); + break; + default: + break; + } + } + + return (-1); +} + +static int +is_hostent_equal(struct hostent *he, struct addrinfo *ai) +{ + char **cp; + int rv; + +#ifdef DEBUG + printf("checking equality of he and ai\n"); +#endif + + rv = check_addrinfo_for_name(ai, he->h_name); + if (rv != 0) { + printf("not equal - he->h_name couldn't be found\n"); + return (rv); + } + + for (cp = he->h_addr_list; *cp; ++cp) { + rv = check_addrinfo_for_addr(ai, *cp, he->h_length, + he->h_addrtype); + if (rv != 0) { + printf("not equal - one of he->h_addr_list couldn't be found\n"); + return (rv); + } + } + +#ifdef DEBUG + printf("equal\n"); +#endif + + return (0); +} + +static void +sdump_hostent(struct hostent *ht, char *buffer, size_t buflen) +{ + char **cp; + size_t i; + int written; + + written = snprintf(buffer, buflen, "%s %d %d", + ht->h_name, ht->h_addrtype, ht->h_length); + buffer += written; + if (written > buflen) + return; + buflen -= written; + + if (ht->h_aliases != NULL) { + if (*(ht->h_aliases) != NULL) { + for (cp = ht->h_aliases; *cp; ++cp) { + written = snprintf(buffer, buflen, " %s",*cp); + buffer += written; + if (written > buflen) + return; + buflen -= written; + + if (buflen == 0) + return; + } + } else { + written = snprintf(buffer, buflen, " noaliases"); + buffer += written; + if (written > buflen) + return; + buflen -= written; + } + } else { + written = snprintf(buffer, buflen, " (null)"); + buffer += written; + if (written > buflen) + return; + buflen -= written; + } + + written = snprintf(buffer, buflen, " : "); + buffer += written; + if (written > buflen) + return; + buflen -= written; + + if (ht->h_addr_list != NULL) { + if (*(ht->h_addr_list) != NULL) { + for (cp = ht->h_addr_list; *cp; ++cp) { + for (i = 0; i < ht->h_length; ++i ) { + written = snprintf(buffer, buflen, + i + 1 != ht->h_length ? "%d." : "%d", + (unsigned char)(*cp)[i]); + buffer += written; + if (written > buflen) + return; + buflen -= written; + + if (buflen == 0) + return; + } + + if (*(cp + 1) ) { + written = snprintf(buffer, buflen, " "); + buffer += written; + if (written > buflen) + return; + buflen -= written; + } + } + } else { + written = snprintf(buffer, buflen, " noaddrs"); + buffer += written; + if (written > buflen) + return; + buflen -= written; + } + } else { + written = snprintf(buffer, buflen, " (null)"); + buffer += written; + if (written > buflen) + return; + buflen -= written; + } +} + +static int +hostent_read_hostlist_func(struct hostent *he, char *line) +{ + struct hostent *result; + int rv; + +#ifdef DEBUG + printf("resolving %s: ", line); +#endif + result = __gethostbyname2(line, af_type); + if (result != NULL) { +#ifdef DEBUG + printf("found\n"); +#endif + + rv = hostent_test_correctness(result, NULL); + if (rv != 0) { + __freehostent(result); + return (rv); + } + + clone_hostent(he, result); + __freehostent(result); + } else { +#ifdef DEBUG + printf("not found\n"); +#endif + memset(he, 0, sizeof(struct hostent)); + he->h_name = strdup(line); + ATF_REQUIRE(he->h_name != NULL); + } + return (0); +} + +static int +hostent_read_snapshot_addr(char *addr, unsigned char *result, size_t len) +{ + char *s, *ps, *ts; + + ps = addr; + while ( (s = strsep(&ps, ".")) != NULL) { + if (len == 0) + return (-1); + + *result = (unsigned char)strtol(s, &ts, 10); + ++result; + if (*ts != '\0') + return (-1); + + --len; + } + if (len != 0) + return (-1); + else + return (0); +} + +static int +hostent_read_snapshot_func(struct hostent *ht, char *line) +{ + StringList *sl1, *sl2; + char *s, *ps, *ts; + int i, rv; + +#ifdef DEBUG + printf("1 line read from snapshot:\n%s\n", line); +#endif + + rv = 0; + i = 0; + sl1 = sl2 = NULL; + ps = line; + memset(ht, 0, sizeof(struct hostent)); + while ((s = strsep(&ps, " ")) != NULL) { + switch (i) { + case 0: + ht->h_name = strdup(s); + ATF_REQUIRE(ht->h_name != NULL); + break; + + case 1: + ht->h_addrtype = (int)strtol(s, &ts, 10); + if (*ts != '\0') + goto fin; + break; + + case 2: + ht->h_length = (int)strtol(s, &ts, 10); + if (*ts != '\0') + goto fin; + break; + + case 3: + if (sl1 == NULL) { + if (strcmp(s, "(null)") == 0) + return (0); + + sl1 = sl_init(); + ATF_REQUIRE(sl1 != NULL); + + if (strcmp(s, "noaliases") != 0) { + ts = strdup(s); + ATF_REQUIRE(ts != NULL); + sl_add(sl1, ts); + } + } else { + if (strcmp(s, ":") == 0) + ++i; + else { + ts = strdup(s); + ATF_REQUIRE(ts != NULL); + sl_add(sl1, ts); + } + } + break; + + case 4: + if (sl2 == NULL) { + if (strcmp(s, "(null)") == 0) + return (0); + + sl2 = sl_init(); + ATF_REQUIRE(sl2 != NULL); + + if (strcmp(s, "noaddrs") != 0) { + ts = calloc(1, ht->h_length); + ATF_REQUIRE(ts != NULL); + rv = hostent_read_snapshot_addr(s, + (unsigned char *)ts, + ht->h_length); + sl_add(sl2, ts); + if (rv != 0) + goto fin; + } + } else { + ts = calloc(1, ht->h_length); + ATF_REQUIRE(ts != NULL); + rv = hostent_read_snapshot_addr(s, + (unsigned char *)ts, ht->h_length); + sl_add(sl2, ts); + if (rv != 0) + goto fin; + } + break; + default: + break; + } + + if (i != 3 && i != 4) + ++i; + } + +fin: + if (sl1 != NULL) { + sl_add(sl1, NULL); + ht->h_aliases = sl1->sl_str; + } + if (sl2 != NULL) { + sl_add(sl2, NULL); + ht->h_addr_list = sl2->sl_str; + } + + if ((i != 4) || (rv != 0)) { + free_hostent(ht); + memset(ht, 0, sizeof(struct hostent)); + return (-1); + } + + /* NOTE: is it a dirty hack or not? */ + free(sl1); + free(sl2); + return (0); +} + +static void +dump_hostent(struct hostent *result) +{ + if (result != NULL) { + char buffer[1024]; + sdump_hostent(result, buffer, sizeof(buffer)); + printf("%s\n", buffer); + } else + printf("(null)\n"); +} + +static int +hostent_test_correctness(struct hostent *ht, void *mdata) +{ + +#ifdef DEBUG + printf("testing correctness with the following data:\n"); + dump_hostent(ht); +#endif + + if (ht == NULL) + goto errfin; + + if (ht->h_name == NULL) + goto errfin; + + if (!((ht->h_addrtype >= 0) && (ht->h_addrtype < AF_MAX))) + goto errfin; + + if ((ht->h_length != sizeof(struct in_addr)) && + (ht->h_length != sizeof(struct in6_addr))) + goto errfin; + + if (ht->h_aliases == NULL) + goto errfin; + + if (ht->h_addr_list == NULL) + goto errfin; + +#ifdef DEBUG + printf("correct\n"); +#endif + + return (0); +errfin: + printf("incorrect\n"); + + return (-1); +} + +static int +hostent_test_gethostbyaddr(struct hostent *he, void *mdata) +{ + struct hostent *result; + struct hostent_test_data *addr_test_data; + int rv; + + addr_test_data = (struct hostent_test_data *)mdata; + + /* We should omit unresolved hostents */ + if (he->h_addr_list != NULL) { + char **cp; + for (cp = he->h_addr_list; *cp; ++cp) { +#ifdef DEBUG + printf("doing reverse lookup for %s\n", he->h_name); +#endif + + result = __gethostbyaddr(*cp, he->h_length, + he->h_addrtype); + if (result == NULL) { +#ifdef DEBUG + printf("%s: warning: reverse lookup failed " + "for %s: %s\n", __func__, he->h_name, + strerror(errno)); +#endif + continue; + } + rv = hostent_test_correctness(result, NULL); + if (rv != 0) { + __freehostent(result); + return (rv); + } + + if (addr_test_data != NULL) + TEST_DATA_APPEND(hostent, addr_test_data, + result); + + __freehostent(result); + } + } + + return (0); +} + +static int +hostent_test_getaddrinfo_eq(struct hostent *he, void *mdata) +{ + struct addrinfo *ai, hints; + int rv; + + ai = NULL; + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = af_type; + hints.ai_flags = AI_CANONNAME; + + printf("using getaddrinfo() to resolve %s\n", he->h_name); + + /* struct hostent *he was not resolved */ + if (he->h_addr_list == NULL) { + /* We can be sure that he->h_name is not NULL */ + rv = getaddrinfo(he->h_name, NULL, &hints, &ai); + if (rv == 0) { + printf("not ok - shouldn't have been resolved\n"); + return (-1); + } + } else { + rv = getaddrinfo(he->h_name, NULL, &hints, &ai); + if (rv != 0) { + printf("not ok - should have been resolved\n"); + return (-1); + } + + rv = is_hostent_equal(he, ai); + if (rv != 0) { + printf("not ok - addrinfo and hostent are not equal\n"); + return (-1); + } + + } + + return (0); +} + +static int +hostent_test_getnameinfo_eq(struct hostent *he, void *mdata) +{ + char **cp; + char buffer[NI_MAXHOST]; + struct sockaddr_in sin; + struct sockaddr_in6 sin6; + struct sockaddr *saddr; + struct hostent *result; + int i, rv; + + if (he->h_addr_list == NULL) + return (0); + + for (cp = he->h_addr_list; *cp; ++cp) { +#ifdef DEBUG + printf("doing reverse lookup for %s\n", he->h_name); +#endif + result = __gethostbyaddr(*cp, he->h_length, + he->h_addrtype); + if (result != NULL) { + rv = hostent_test_correctness(result, NULL); + if (rv != 0) { + __freehostent(result); + return (rv); + } + } else + printf("%s: warning: reverse lookup failed " + "for %s: %s\n", __func__, he->h_name, + strerror(errno)); + + switch (he->h_addrtype) { + case AF_INET: + memset(&sin, 0, sizeof(struct sockaddr_in)); + sin.sin_len = sizeof(struct sockaddr_in); + sin.sin_family = AF_INET; + memcpy(&sin.sin_addr, *cp, he->h_length); + + saddr = (struct sockaddr *)&sin; + break; + case AF_INET6: + memset(&sin6, 0, sizeof(struct sockaddr_in6)); + sin6.sin6_len = sizeof(struct sockaddr_in6); + sin6.sin6_family = AF_INET6; + memcpy(&sin6.sin6_addr, *cp, he->h_length); + + saddr = (struct sockaddr *)&sin6; + break; + default: + printf("warning: %d family is unsupported\n", + he->h_addrtype); + continue; + } + + ATF_REQUIRE(saddr != NULL); + rv = getnameinfo(saddr, saddr->sa_len, buffer, + sizeof(buffer), NULL, 0, NI_NAMEREQD); + + if (rv != 0 && result != NULL) { + printf("getnameinfo() didn't make the reverse " + "lookup, when it should have (%s)\n", + gai_strerror(rv)); + return (rv); + } + + if (rv == 0 && result == NULL) { + printf("getnameinfo() made the " + "reverse lookup, when it shouldn't have\n"); + return (rv); + } + + if (rv != 0 && result == NULL) { +#ifdef DEBUG + printf("both getnameinfo() and ***byaddr() failed as " + "expected\n"); +#endif + continue; + } + +#ifdef DEBUG + printf("comparing %s with %s\n", result->h_name, + buffer); +#endif + + /* + * An address might reverse resolve to hostname alias or the + * official hostname, e.g. moon.vub.ac.be. + */ + bool found_a_match; + + if (strcmp(result->h_name, buffer) == 0) { + found_a_match = true; +#ifdef DEBUG + printf("matched official hostname\n"); +#endif + } else { + for (i = 0; i < nitems(result->h_aliases); i++) { + printf("[%d] resolved: %s\n", i, + result->h_aliases[i]); + if (strcmp(result->h_aliases[i], + buffer) == 0) { + printf("matched hostname alias\n"); + found_a_match = true; + break; + } + } + } + __freehostent(result); + + if (found_a_match) { +#ifdef DEBUG + printf("getnameinfo() and ***byaddr() results are " + "equal\n"); +#endif + } else { + printf("getnameinfo() and ***byaddr() results are not " + "equal for %s\n", he->h_name); + return (-1); + } + } + + return (0); +} + +int +run_tests(const char *hostlist_file, const char *snapshot_file, int af_type, + enum test_methods method, bool use_ipv6_mapping) +{ + struct hostent_test_data td, td_addr, td_snap; + res_state statp; + int rv = -2; + + switch (af_type) { + case AF_INET: + ATF_REQUIRE_FEATURE("inet"); + ATF_REQUIRE(!use_ipv6_mapping); + break; + case AF_INET6: + ATF_REQUIRE_FEATURE("inet6"); + break; + default: + atf_tc_fail("unhandled address family: %d", af_type); + break; + } + + if (!use_ipnode_functions) { + statp = __res_state(); + if (statp == NULL || ((statp->options & RES_INIT) == 0 && + res_ninit(statp) == -1)) { + printf("error: can't init res_state\n"); + + return (-1); + } + + if (use_ipv6_mapping) + statp->options |= RES_USE_INET6; + else + statp->options &= ~RES_USE_INET6; + } + + TEST_DATA_INIT(hostent, &td, clone_hostent, free_hostent); + TEST_DATA_INIT(hostent, &td_addr, clone_hostent, free_hostent); + TEST_DATA_INIT(hostent, &td_snap, clone_hostent, free_hostent); + + if (access(hostlist_file, R_OK) != 0) { + printf("can't access the hostlist file %s\n", hostlist_file); + rv = -1; + goto fin; + } + +#ifdef DEBUG + printf("building host lists from %s\n", hostlist_file); +#endif + + rv = TEST_SNAPSHOT_FILE_READ(hostent, hostlist_file, &td, + hostent_read_hostlist_func); + if (rv != 0) { + printf("failed to read the host list file: %s\n", + hostlist_file); + goto fin; + } + + if (snapshot_file != NULL) { + if (access(snapshot_file, W_OK | R_OK) != 0) { + if (errno == ENOENT) { + if (method != TEST_GETHOSTBYADDR) + method = TEST_BUILD_SNAPSHOT; + else + method = TEST_BUILD_ADDR_SNAPSHOT; + } else { + printf("can't access the snapshot file %s\n", + snapshot_file); + rv = -1; + goto fin; + } + } else { + rv = TEST_SNAPSHOT_FILE_READ(hostent, snapshot_file, + &td_snap, hostent_read_snapshot_func); + if (rv != 0) { + printf("error reading snapshot file\n"); + goto fin; + } + } + } + + switch (method) { + case TEST_GETHOSTBYNAME2: + if (snapshot_file != NULL) + rv = DO_2PASS_TEST(hostent, &td, &td_snap, + compare_hostent, NULL); + break; + case TEST_GETHOSTBYADDR: + rv = DO_1PASS_TEST(hostent, &td, + hostent_test_gethostbyaddr, (void *)&td_addr); + if (rv != 0) + goto fin; + + if (snapshot_file != NULL) + rv = DO_2PASS_TEST(hostent, &td_addr, &td_snap, + compare_hostent, NULL); + break; + case TEST_GETHOSTBYNAME2_GETADDRINFO: + rv = DO_1PASS_TEST(hostent, &td, + hostent_test_getaddrinfo_eq, NULL); + break; + case TEST_GETHOSTBYADDR_GETNAMEINFO: + rv = DO_1PASS_TEST(hostent, &td, + hostent_test_getnameinfo_eq, NULL); + break; + case TEST_BUILD_SNAPSHOT: + if (snapshot_file != NULL) { + rv = TEST_SNAPSHOT_FILE_WRITE(hostent, snapshot_file, + &td, sdump_hostent); + } + break; + case TEST_BUILD_ADDR_SNAPSHOT: + if (snapshot_file != NULL) { + rv = DO_1PASS_TEST(hostent, &td, + hostent_test_gethostbyaddr, (void *)&td_addr); + if (rv != 0) + goto fin; + rv = TEST_SNAPSHOT_FILE_WRITE(hostent, snapshot_file, + &td_addr, sdump_hostent); + } + break; + default: + rv = 0; + break; + } + +fin: + TEST_DATA_DESTROY(hostent, &td_snap); + TEST_DATA_DESTROY(hostent, &td_addr); + TEST_DATA_DESTROY(hostent, &td); + + return (rv); +} + +#define HOSTLIST_FILE "mach" + +#define _RUN_TESTS(tc, snapshot_file, af_type, method, use_ipv6_mapping) \ +do { \ + char *_hostlist_file; \ + char *_snapshot_file; \ + ATF_REQUIRE(0 < asprintf(&_hostlist_file, "%s/%s", \ + atf_tc_get_config_var(tc, "srcdir"), HOSTLIST_FILE)); \ + if (snapshot_file == NULL) \ + _snapshot_file = NULL; \ + else { \ + _snapshot_file = strdup(snapshot_file); \ + ATF_REQUIRE(_snapshot_file != NULL); \ + } \ + ATF_REQUIRE(run_tests(_hostlist_file, _snapshot_file, af_type, \ + method, use_ipv6_mapping) == 0); \ +} while(0) + +#define RUN_HOST_TESTS(tc, snapshot_file, af_type, method, use_ipv6_mapping) \ +do { \ + use_ipnode_functions = false; \ + _RUN_TESTS(tc, snapshot_file, af_type, method, use_ipv6_mapping); \ +} while(0) + +#define RUN_IPNODE_TESTS(tc, snapshot_file, af_type, method, use_ipv6_mapping) \ +do { \ + use_ipnode_functions = true; \ + _RUN_TESTS(tc, snapshot_file, af_type, method, use_ipv6_mapping); \ +} while(0) + +ATF_TC_WITHOUT_HEAD(gethostbyaddr_ipv4); +ATF_TC_BODY(gethostbyaddr_ipv4, tc) +{ + + RUN_HOST_TESTS(tc, NULL, AF_INET, TEST_GETHOSTBYADDR, false); +} + +ATF_TC_WITHOUT_HEAD(gethostbyaddr_ipv4_with_snapshot); +ATF_TC_BODY(gethostbyaddr_ipv4_with_snapshot, tc) +{ + + RUN_HOST_TESTS(tc, "snapshot_htaddr4", AF_INET, TEST_GETHOSTBYADDR, false); +} + +ATF_TC_WITHOUT_HEAD(gethostbyaddr_ipv6); +ATF_TC_BODY(gethostbyaddr_ipv6, tc) +{ + + RUN_HOST_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYADDR, false); +} + +ATF_TC_WITHOUT_HEAD(gethostbyaddr_ipv6_AI_V4MAPPED); +ATF_TC_BODY(gethostbyaddr_ipv6_AI_V4MAPPED, tc) +{ + + ipnode_flags = AI_V4MAPPED; + RUN_HOST_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYADDR, true); +} + +ATF_TC_WITHOUT_HEAD(gethostbyaddr_ipv6_with_snapshot); +ATF_TC_BODY(gethostbyaddr_ipv6_with_snapshot, tc) +{ + + RUN_HOST_TESTS(tc, "snapshot_htaddr6", AF_INET6, TEST_GETHOSTBYADDR, false); +} + +ATF_TC_WITHOUT_HEAD(gethostbyaddr_ipv6_with_snapshot_AI_V4MAPPED); +ATF_TC_BODY(gethostbyaddr_ipv6_with_snapshot_AI_V4MAPPED, tc) +{ + + ipnode_flags = AI_V4MAPPED; + RUN_HOST_TESTS(tc, "snapshot_htaddr6map", AF_INET6, TEST_GETHOSTBYADDR, true); +} + +ATF_TC_WITHOUT_HEAD(gethostbyname2_getaddrinfo_ipv4); +ATF_TC_BODY(gethostbyname2_getaddrinfo_ipv4, tc) +{ + + RUN_HOST_TESTS(tc, NULL, AF_INET, TEST_GETHOSTBYNAME2_GETADDRINFO, false); +} + +ATF_TC_WITHOUT_HEAD(gethostbyname2_getaddrinfo_ipv6); +ATF_TC_BODY(gethostbyname2_getaddrinfo_ipv6, tc) +{ + + RUN_HOST_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2_GETADDRINFO, false); +} + +ATF_TC_WITHOUT_HEAD(gethostbyaddr_getnameinfo_ipv4); +ATF_TC_BODY(gethostbyaddr_getnameinfo_ipv4, tc) +{ + + RUN_HOST_TESTS(tc, NULL, AF_INET, TEST_GETHOSTBYADDR_GETNAMEINFO, false); +} + +ATF_TC_WITHOUT_HEAD(gethostbyaddr_getnameinfo_ipv6); +ATF_TC_BODY(gethostbyaddr_getnameinfo_ipv6, tc) +{ + + RUN_HOST_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYADDR_GETNAMEINFO, false); +} + +ATF_TC_WITHOUT_HEAD(gethostbyname2_ipv4); +ATF_TC_BODY(gethostbyname2_ipv4, tc) +{ + + RUN_HOST_TESTS(tc, NULL, AF_INET, TEST_GETHOSTBYNAME2, false); +} + +ATF_TC_WITHOUT_HEAD(gethostbyname2_ipv4_with_snapshot); +ATF_TC_BODY(gethostbyname2_ipv4_with_snapshot, tc) +{ + + RUN_HOST_TESTS(tc, "snapshot_htname4", AF_INET, TEST_GETHOSTBYNAME2, false); +} + +ATF_TC_WITHOUT_HEAD(gethostbyname2_ipv6); +ATF_TC_BODY(gethostbyname2_ipv6, tc) +{ + + RUN_HOST_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2, false); +} + +ATF_TC_WITHOUT_HEAD(gethostbyname2_ipv6_AI_V4MAPPED); +ATF_TC_BODY(gethostbyname2_ipv6_AI_V4MAPPED, tc) +{ + + ipnode_flags = AI_V4MAPPED; + RUN_HOST_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2, true); +} + +ATF_TC_WITHOUT_HEAD(gethostbyname2_ipv6_with_snapshot); +ATF_TC_BODY(gethostbyname2_ipv6_with_snapshot, tc) +{ + + RUN_HOST_TESTS(tc, "snapshot_htname6", AF_INET6, TEST_GETHOSTBYNAME2, false); +} + +ATF_TC_WITHOUT_HEAD(gethostbyname2_ipv6_with_snapshot_AI_V4MAPPED); +ATF_TC_BODY(gethostbyname2_ipv6_with_snapshot_AI_V4MAPPED, tc) +{ + + ipnode_flags = AI_V4MAPPED; + RUN_HOST_TESTS(tc, "snapshot_htname6map", AF_INET6, TEST_GETHOSTBYNAME2, true); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv4); +ATF_TC_BODY(getipnodebyaddr_ipv4, tc) +{ + + RUN_IPNODE_TESTS(tc, NULL, AF_INET, TEST_GETHOSTBYADDR, false); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv4_with_snapshot); +ATF_TC_BODY(getipnodebyaddr_ipv4_with_snapshot, tc) +{ + + RUN_IPNODE_TESTS(tc, "snapshot_ipnodeaddr4", AF_INET, TEST_GETHOSTBYADDR, false); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyaddr_getnameinfo_ipv4); +ATF_TC_BODY(getipnodebyaddr_getnameinfo_ipv4, tc) +{ + + RUN_IPNODE_TESTS(tc, NULL, AF_INET, TEST_GETHOSTBYADDR_GETNAMEINFO, false); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv6); +ATF_TC_BODY(getipnodebyaddr_ipv6, tc) +{ + + RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYADDR, false); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv6_AI_V4MAPPED); +ATF_TC_BODY(getipnodebyaddr_ipv6_AI_V4MAPPED, tc) +{ + + ipnode_flags = AI_V4MAPPED; + RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYADDR, true); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv6_AI_V4MAPPED_CFG); +ATF_TC_BODY(getipnodebyaddr_ipv6_AI_V4MAPPED_CFG, tc) +{ + + ipnode_flags = AI_V4MAPPED_CFG; + RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYADDR, true); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv6_AI_V4MAPPED_CFG_AI_ALL); +ATF_TC_BODY(getipnodebyaddr_ipv6_AI_V4MAPPED_CFG_AI_ALL, tc) +{ + + ipnode_flags = AI_V4MAPPED_CFG | AI_ALL; + RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYADDR, true); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv6_with_snapshot); +ATF_TC_BODY(getipnodebyaddr_ipv6_with_snapshot, tc) +{ + + RUN_IPNODE_TESTS(tc, "snapshot_ipnodeaddr6", AF_INET6, TEST_GETHOSTBYADDR, false); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv6_with_snapshot_AI_V4MAPPED); +ATF_TC_BODY(getipnodebyaddr_ipv6_with_snapshot_AI_V4MAPPED, tc) +{ + + ipnode_flags = AI_V4MAPPED; + RUN_IPNODE_TESTS(tc, + "snapshot_ipnodeaddr6_AI_V4MAPPED", AF_INET6, + TEST_GETHOSTBYADDR, true); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv6_with_snapshot_AI_V4MAPPED_CFG); +ATF_TC_BODY(getipnodebyaddr_ipv6_with_snapshot_AI_V4MAPPED_CFG, tc) +{ + + ipnode_flags = AI_V4MAPPED_CFG; + RUN_IPNODE_TESTS(tc, + "snapshot_ipnodeaddr6_AI_V4MAPPED_CFG", AF_INET6, + TEST_GETHOSTBYADDR, true); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyaddr_ipv6_with_snapshot_AI_V4MAPPED_CFG_AI_ALL); +ATF_TC_BODY(getipnodebyaddr_ipv6_with_snapshot_AI_V4MAPPED_CFG_AI_ALL, tc) +{ + + ipnode_flags = AI_V4MAPPED_CFG | AI_ALL; + RUN_IPNODE_TESTS(tc, + "snapshot_ipnodeaddr6_AI_V4MAPPED_CFG_AI_ALL", AF_INET6, + TEST_GETHOSTBYADDR, true); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyaddr_getnameinfo_ipv6); +ATF_TC_BODY(getipnodebyaddr_getnameinfo_ipv6, tc) +{ + + RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYADDR_GETNAMEINFO, false); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv4); +ATF_TC_BODY(getipnodebyname_ipv4, tc) +{ + + RUN_IPNODE_TESTS(tc, NULL, AF_INET, TEST_GETHOSTBYNAME2, false); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv4_with_snapshot); +ATF_TC_BODY(getipnodebyname_ipv4_with_snapshot, tc) +{ + + RUN_IPNODE_TESTS(tc, "snapshot_ipnodename4", AF_INET, TEST_GETHOSTBYNAME2, false); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv4_AI_ADDRCONFIG); +ATF_TC_BODY(getipnodebyname_ipv4_AI_ADDRCONFIG, tc) +{ + + ipnode_flags = AI_ADDRCONFIG; + RUN_IPNODE_TESTS(tc, NULL, AF_INET, TEST_GETHOSTBYNAME2, false); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv4_with_snapshot_AI_ADDRCONFIG); +ATF_TC_BODY(getipnodebyname_ipv4_with_snapshot_AI_ADDRCONFIG, tc) +{ + + ipnode_flags = AI_ADDRCONFIG; + RUN_IPNODE_TESTS(tc, "snapshot_ipnodename4_AI_ADDRCONFIG", AF_INET, + TEST_GETHOSTBYNAME2, false); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyname_getaddrinfo_ipv4); +ATF_TC_BODY(getipnodebyname_getaddrinfo_ipv4, tc) +{ + + RUN_IPNODE_TESTS(tc, NULL, AF_INET, TEST_GETHOSTBYNAME2_GETADDRINFO, false); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6); +ATF_TC_BODY(getipnodebyname_ipv6, tc) +{ + + RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2, false); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_with_snapshot); +ATF_TC_BODY(getipnodebyname_ipv6_with_snapshot, tc) +{ + + RUN_IPNODE_TESTS(tc, "snapshot_ipnodename6", AF_INET6, TEST_GETHOSTBYNAME2, false); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_AI_ADDRCONFIG); +ATF_TC_BODY(getipnodebyname_ipv6_AI_ADDRCONFIG, tc) +{ + + ipnode_flags = AI_ADDRCONFIG; + RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2, false); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_AI_V4MAPPED); +ATF_TC_BODY(getipnodebyname_ipv6_AI_V4MAPPED, tc) +{ + + ipnode_flags = AI_V4MAPPED; + RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2, true); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_AI_V4MAPPED_CFG); +ATF_TC_BODY(getipnodebyname_ipv6_AI_V4MAPPED_CFG, tc) +{ + + ipnode_flags = AI_V4MAPPED_CFG; + RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2, true); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_AI_V4MAPPED_CFG_AI_ADDRCONFIG); +ATF_TC_BODY(getipnodebyname_ipv6_AI_V4MAPPED_CFG_AI_ADDRCONFIG, tc) +{ + + ipnode_flags = AI_V4MAPPED_CFG | AI_ADDRCONFIG; + RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2, false); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_AI_V4MAPPED_CFG_AI_ALL); +ATF_TC_BODY(getipnodebyname_ipv6_AI_V4MAPPED_CFG_AI_ALL, tc) +{ + + ipnode_flags = AI_V4MAPPED_CFG | AI_ALL; + RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2, true); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED); +ATF_TC_BODY(getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED, tc) +{ + + ipnode_flags = AI_V4MAPPED; + RUN_IPNODE_TESTS(tc, + "snapshot_ipnodename6_AI_V4MAPPED", AF_INET6, + TEST_GETHOSTBYNAME2, true); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED_CFG); +ATF_TC_BODY(getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED_CFG, tc) +{ + + ipnode_flags = AI_V4MAPPED_CFG; + RUN_IPNODE_TESTS(tc, + "snapshot_ipnodename6_AI_V4MAPPED_CFG", AF_INET6, + TEST_GETHOSTBYNAME2, true); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED_CFG_AI_ADDRCONFIG); +ATF_TC_BODY(getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED_CFG_AI_ADDRCONFIG, tc) +{ + + ipnode_flags = AI_V4MAPPED_CFG | AI_ADDRCONFIG; + RUN_IPNODE_TESTS(tc, + "snapshot_ipnodename6_AI_V4MAPPED_CFG_AI_ADDRCONFIG", AF_INET6, + TEST_GETHOSTBYNAME2, false); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED_CFG_AI_ALL); +ATF_TC_BODY(getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED_CFG_AI_ALL, tc) +{ + + ipnode_flags = AI_V4MAPPED_CFG | AI_ALL; + RUN_IPNODE_TESTS(tc, + "snapshot_ipnodename6_AI_V4MAPPED_CFG_AI_ALL", AF_INET6, + TEST_GETHOSTBYNAME2, true); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyname_ipv6_with_snapshot_AI_ADDRCONFIG); +ATF_TC_BODY(getipnodebyname_ipv6_with_snapshot_AI_ADDRCONFIG, tc) +{ + + ipnode_flags = AI_ADDRCONFIG; + RUN_IPNODE_TESTS(tc, "snapshot_ipnodename6_AI_ADDRCONFIG", AF_INET6, + TEST_GETHOSTBYNAME2, false); +} + +ATF_TC_WITHOUT_HEAD(getipnodebyname_getaddrinfo_ipv6); +ATF_TC_BODY(getipnodebyname_getaddrinfo_ipv6, tc) +{ + + RUN_IPNODE_TESTS(tc, NULL, AF_INET6, TEST_GETHOSTBYNAME2_GETADDRINFO, false); +} + +ATF_TP_ADD_TCS(tp) +{ + + /* gethostbyaddr */ + ATF_TP_ADD_TC(tp, gethostbyaddr_ipv4); + ATF_TP_ADD_TC(tp, gethostbyaddr_ipv4_with_snapshot); + ATF_TP_ADD_TC(tp, gethostbyaddr_ipv6); + ATF_TP_ADD_TC(tp, gethostbyaddr_ipv6_AI_V4MAPPED); /* XXX */ + ATF_TP_ADD_TC(tp, gethostbyaddr_ipv6_with_snapshot); + ATF_TP_ADD_TC(tp, gethostbyaddr_ipv6_with_snapshot_AI_V4MAPPED); + ATF_TP_ADD_TC(tp, gethostbyaddr_getnameinfo_ipv4); + ATF_TP_ADD_TC(tp, gethostbyaddr_getnameinfo_ipv6); + + /* gethostbyname2 */ + ATF_TP_ADD_TC(tp, gethostbyname2_getaddrinfo_ipv4); + ATF_TP_ADD_TC(tp, gethostbyname2_getaddrinfo_ipv6); + ATF_TP_ADD_TC(tp, gethostbyname2_ipv4); + ATF_TP_ADD_TC(tp, gethostbyname2_ipv4_with_snapshot); + ATF_TP_ADD_TC(tp, gethostbyname2_ipv6); + ATF_TP_ADD_TC(tp, gethostbyname2_ipv6_AI_V4MAPPED); + ATF_TP_ADD_TC(tp, gethostbyname2_ipv6_with_snapshot); + ATF_TP_ADD_TC(tp, gethostbyname2_ipv6_with_snapshot_AI_V4MAPPED); + + /* getipnodebyaddr */ + ATF_TP_ADD_TC(tp, getipnodebyaddr_ipv4); + ATF_TP_ADD_TC(tp, getipnodebyaddr_ipv4_with_snapshot); + ATF_TP_ADD_TC(tp, getipnodebyaddr_getnameinfo_ipv4); + ATF_TP_ADD_TC(tp, getipnodebyaddr_ipv6); + ATF_TP_ADD_TC(tp, getipnodebyaddr_ipv6_AI_V4MAPPED); + ATF_TP_ADD_TC(tp, getipnodebyaddr_ipv6_AI_V4MAPPED_CFG); + ATF_TP_ADD_TC(tp, getipnodebyaddr_ipv6_AI_V4MAPPED_CFG_AI_ALL); + ATF_TP_ADD_TC(tp, getipnodebyaddr_ipv6_with_snapshot); + ATF_TP_ADD_TC(tp, getipnodebyaddr_ipv6_with_snapshot_AI_V4MAPPED); + ATF_TP_ADD_TC(tp, getipnodebyaddr_ipv6_with_snapshot_AI_V4MAPPED_CFG); + ATF_TP_ADD_TC(tp, getipnodebyaddr_ipv6_with_snapshot_AI_V4MAPPED_CFG_AI_ALL); + ATF_TP_ADD_TC(tp, getipnodebyaddr_getnameinfo_ipv6); + + /* getipnodebyname */ + ATF_TP_ADD_TC(tp, getipnodebyname_ipv4); + ATF_TP_ADD_TC(tp, getipnodebyname_ipv4_with_snapshot); + ATF_TP_ADD_TC(tp, getipnodebyname_ipv4_AI_ADDRCONFIG); + ATF_TP_ADD_TC(tp, getipnodebyname_ipv4_with_snapshot_AI_ADDRCONFIG); + ATF_TP_ADD_TC(tp, getipnodebyname_getaddrinfo_ipv4); + ATF_TP_ADD_TC(tp, getipnodebyname_ipv6); + ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_with_snapshot); + ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_AI_ADDRCONFIG); + ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_AI_V4MAPPED); + ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_AI_V4MAPPED_CFG); + ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_AI_V4MAPPED_CFG_AI_ADDRCONFIG); + ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_AI_V4MAPPED_CFG_AI_ALL); + ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED); + ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED_CFG); + ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED_CFG_AI_ADDRCONFIG); + ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_with_snapshot_AI_V4MAPPED_CFG_AI_ALL); + ATF_TP_ADD_TC(tp, getipnodebyname_ipv6_with_snapshot_AI_ADDRCONFIG); + ATF_TP_ADD_TC(tp, getipnodebyname_getaddrinfo_ipv6); + + return (atf_no_error()); +} Property changes on: user/ngie/stable-10-libnv/lib/libc/tests/nss/gethostby_test.c ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: user/ngie/stable-10-libnv/lib/libc/tests/nss/getproto_test.c =================================================================== --- user/ngie/stable-10-libnv/lib/libc/tests/nss/getproto_test.c (nonexistent) +++ user/ngie/stable-10-libnv/lib/libc/tests/nss/getproto_test.c (revision 292857) @@ -0,0 +1,556 @@ +/*- + * Copyright (c) 2006 Michael Bushkov + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "testutil.h" + +enum test_methods { + TEST_GETPROTOENT, + TEST_GETPROTOBYNAME, + TEST_GETPROTOBYNUMBER, + TEST_GETPROTOENT_2PASS, + TEST_BUILD_SNAPSHOT +}; + +DECLARE_TEST_DATA(protoent) +DECLARE_TEST_FILE_SNAPSHOT(protoent) +DECLARE_1PASS_TEST(protoent) +DECLARE_2PASS_TEST(protoent) + +static void clone_protoent(struct protoent *, struct protoent const *); +static int compare_protoent(struct protoent *, struct protoent *, void *); +static void dump_protoent(struct protoent *); +static void free_protoent(struct protoent *); + +static void sdump_protoent(struct protoent *, char *, size_t); +static int protoent_read_snapshot_func(struct protoent *, char *); + +static int protoent_check_ambiguity(struct protoent_test_data *, + struct protoent *); +static int protoent_fill_test_data(struct protoent_test_data *); +static int protoent_test_correctness(struct protoent *, void *); +static int protoent_test_getprotobyname(struct protoent *, void *); +static int protoent_test_getprotobynumber(struct protoent *, void *); +static int protoent_test_getprotoent(struct protoent *, void *); + +IMPLEMENT_TEST_DATA(protoent) +IMPLEMENT_TEST_FILE_SNAPSHOT(protoent) +IMPLEMENT_1PASS_TEST(protoent) +IMPLEMENT_2PASS_TEST(protoent) + +static void +clone_protoent(struct protoent *dest, struct protoent const *src) +{ + assert(dest != NULL); + assert(src != NULL); + + char **cp; + int aliases_num; + + memset(dest, 0, sizeof(struct protoent)); + + if (src->p_name != NULL) { + dest->p_name = strdup(src->p_name); + assert(dest->p_name != NULL); + } + + dest->p_proto = src->p_proto; + + if (src->p_aliases != NULL) { + aliases_num = 0; + for (cp = src->p_aliases; *cp; ++cp) + ++aliases_num; + + dest->p_aliases = calloc(1, (aliases_num+1) * sizeof(char *)); + assert(dest->p_aliases != NULL); + + for (cp = src->p_aliases; *cp; ++cp) { + dest->p_aliases[cp - src->p_aliases] = strdup(*cp); + assert(dest->p_aliases[cp - src->p_aliases] != NULL); + } + } +} + +static void +free_protoent(struct protoent *pe) +{ + char **cp; + + assert(pe != NULL); + + free(pe->p_name); + + for (cp = pe->p_aliases; *cp; ++cp) + free(*cp); + free(pe->p_aliases); +} + +static int +compare_protoent(struct protoent *pe1, struct protoent *pe2, void *mdata) +{ + char **c1, **c2; + + if (pe1 == pe2) + return 0; + + if ((pe1 == NULL) || (pe2 == NULL)) + goto errfin; + + if ((strcmp(pe1->p_name, pe2->p_name) != 0) || + (pe1->p_proto != pe2->p_proto)) + goto errfin; + + c1 = pe1->p_aliases; + c2 = pe2->p_aliases; + + if ((pe1->p_aliases == NULL) || (pe2->p_aliases == NULL)) + goto errfin; + + for (;*c1 && *c2; ++c1, ++c2) + if (strcmp(*c1, *c2) != 0) + goto errfin; + + if ((*c1 != '\0') || (*c2 != '\0')) + goto errfin; + + return 0; + +errfin: + if (mdata == NULL) { + printf("following structures are not equal:\n"); + dump_protoent(pe1); + dump_protoent(pe2); + } + + return (-1); +} + +static void +sdump_protoent(struct protoent *pe, char *buffer, size_t buflen) +{ + char **cp; + int written; + + written = snprintf(buffer, buflen, "%s %d", + pe->p_name, pe->p_proto); + buffer += written; + if (written > buflen) + return; + buflen -= written; + + if (pe->p_aliases != NULL) { + if (*(pe->p_aliases) != '\0') { + for (cp = pe->p_aliases; *cp; ++cp) { + written = snprintf(buffer, buflen, " %s",*cp); + buffer += written; + if (written > buflen) + return; + buflen -= written; + + if (buflen == 0) + return; + } + } else + snprintf(buffer, buflen, " noaliases"); + } else + snprintf(buffer, buflen, " (null)"); +} + +static int +protoent_read_snapshot_func(struct protoent *pe, char *line) +{ + StringList *sl; + char *s, *ps, *ts; + int i; + + printf("1 line read from snapshot:\n%s\n", line); + + i = 0; + sl = NULL; + ps = line; + memset(pe, 0, sizeof(struct protoent)); + while ( (s = strsep(&ps, " ")) != NULL) { + switch (i) { + case 0: + pe->p_name = strdup(s); + assert(pe->p_name != NULL); + break; + + case 1: + pe->p_proto = (int)strtol(s, &ts, 10); + if (*ts != '\0') { + free(pe->p_name); + return (-1); + } + break; + + default: + if (sl == NULL) { + if (strcmp(s, "(null)") == 0) + return (0); + + sl = sl_init(); + assert(sl != NULL); + + if (strcmp(s, "noaliases") != 0) { + ts = strdup(s); + assert(ts != NULL); + sl_add(sl, ts); + } + } else { + ts = strdup(s); + assert(ts != NULL); + sl_add(sl, ts); + } + break; + } + ++i; + } + + if (i < 3) { + free(pe->p_name); + memset(pe, 0, sizeof(struct protoent)); + return (-1); + } + + sl_add(sl, NULL); + pe->p_aliases = sl->sl_str; + + /* NOTE: is it a dirty hack or not? */ + free(sl); + return (0); +} + +static void +dump_protoent(struct protoent *result) +{ + if (result != NULL) { + char buffer[1024]; + sdump_protoent(result, buffer, sizeof(buffer)); + printf("%s\n", buffer); + } else + printf("(null)\n"); +} + +static int +protoent_fill_test_data(struct protoent_test_data *td) +{ + struct protoent *pe; + + setprotoent(1); + while ((pe = getprotoent()) != NULL) { + if (protoent_test_correctness(pe, NULL) == 0) + TEST_DATA_APPEND(protoent, td, pe); + else + return (-1); + } + endprotoent(); + + return (0); +} + +static int +protoent_test_correctness(struct protoent *pe, void *mdata) +{ + printf("testing correctness with the following data:\n"); + dump_protoent(pe); + + if (pe == NULL) + goto errfin; + + if (pe->p_name == NULL) + goto errfin; + + if (pe->p_proto < 0) + goto errfin; + + if (pe->p_aliases == NULL) + goto errfin; + + printf("correct\n"); + + return (0); +errfin: + printf("incorrect\n"); + + return (-1); +} + +/* protoent_check_ambiguity() is needed when one port+proto is associated with + * more than one peice (these cases are usually marked as PROBLEM in + * /etc/peices. This functions is needed also when one peice+proto is + * associated with several ports. We have to check all the protoent structures + * to make sure that pe really exists and correct */ +static int +protoent_check_ambiguity(struct protoent_test_data *td, struct protoent *pe) +{ + + return (TEST_DATA_FIND(protoent, td, pe, compare_protoent, + NULL) != NULL ? 0 : -1); +} + +static int +protoent_test_getprotobyname(struct protoent *pe_model, void *mdata) +{ + char **alias; + struct protoent *pe; + + printf("testing getprotobyname() with the following data:\n"); + dump_protoent(pe_model); + + pe = getprotobyname(pe_model->p_name); + if (protoent_test_correctness(pe, NULL) != 0) + goto errfin; + + if ((compare_protoent(pe, pe_model, NULL) != 0) && + (protoent_check_ambiguity((struct protoent_test_data *)mdata, pe) + !=0)) + goto errfin; + + for (alias = pe_model->p_aliases; *alias; ++alias) { + pe = getprotobyname(*alias); + + if (protoent_test_correctness(pe, NULL) != 0) + goto errfin; + + if ((compare_protoent(pe, pe_model, NULL) != 0) && + (protoent_check_ambiguity( + (struct protoent_test_data *)mdata, pe) != 0)) + goto errfin; + } + + printf("ok\n"); + return (0); + +errfin: + printf("not ok\n"); + + return (-1); +} + +static int +protoent_test_getprotobynumber(struct protoent *pe_model, void *mdata) +{ + struct protoent *pe; + + printf("testing getprotobyport() with the following data...\n"); + dump_protoent(pe_model); + + pe = getprotobynumber(pe_model->p_proto); + if ((protoent_test_correctness(pe, NULL) != 0) || + ((compare_protoent(pe, pe_model, NULL) != 0) && + (protoent_check_ambiguity((struct protoent_test_data *)mdata, pe) + != 0))) { + printf("not ok\n"); + return (-1); + } else { + printf("ok\n"); + return (0); + } +} + +static int +protoent_test_getprotoent(struct protoent *pe, void *mdata) +{ + /* Only correctness can be checked when doing 1-pass test for + * getprotoent(). */ + return (protoent_test_correctness(pe, NULL)); +} + +int +run_tests(const char *snapshot_file, enum test_methods method) +{ + struct protoent_test_data td, td_snap, td_2pass; + int rv; + + TEST_DATA_INIT(protoent, &td, clone_protoent, free_protoent); + TEST_DATA_INIT(protoent, &td_snap, clone_protoent, free_protoent); + if (snapshot_file != NULL) { + if (access(snapshot_file, W_OK | R_OK) != 0) { + if (errno == ENOENT) + method = TEST_BUILD_SNAPSHOT; + else { + printf("can't access the file %s\n", + snapshot_file); + + rv = -1; + goto fin; + } + } else { + if (method == TEST_BUILD_SNAPSHOT) { + rv = 0; + goto fin; + } + + TEST_SNAPSHOT_FILE_READ(protoent, snapshot_file, + &td_snap, protoent_read_snapshot_func); + } + } + + rv = protoent_fill_test_data(&td); + if (rv == -1) + return (-1); + switch (method) { + case TEST_GETPROTOBYNAME: + if (snapshot_file == NULL) + rv = DO_1PASS_TEST(protoent, &td, + protoent_test_getprotobyname, (void *)&td); + else + rv = DO_1PASS_TEST(protoent, &td_snap, + protoent_test_getprotobyname, (void *)&td_snap); + break; + case TEST_GETPROTOBYNUMBER: + if (snapshot_file == NULL) + rv = DO_1PASS_TEST(protoent, &td, + protoent_test_getprotobynumber, (void *)&td); + else + rv = DO_1PASS_TEST(protoent, &td_snap, + protoent_test_getprotobynumber, (void *)&td_snap); + break; + case TEST_GETPROTOENT: + if (snapshot_file == NULL) + rv = DO_1PASS_TEST(protoent, &td, + protoent_test_getprotoent, (void *)&td); + else + rv = DO_2PASS_TEST(protoent, &td, &td_snap, + compare_protoent, NULL); + break; + case TEST_GETPROTOENT_2PASS: + TEST_DATA_INIT(protoent, &td_2pass, clone_protoent, + free_protoent); + rv = protoent_fill_test_data(&td_2pass); + if (rv != -1) + rv = DO_2PASS_TEST(protoent, &td, &td_2pass, + compare_protoent, NULL); + TEST_DATA_DESTROY(protoent, &td_2pass); + break; + case TEST_BUILD_SNAPSHOT: + if (snapshot_file != NULL) + rv = TEST_SNAPSHOT_FILE_WRITE(protoent, snapshot_file, + &td, sdump_protoent); + break; + default: + rv = 0; + break; + } + +fin: + TEST_DATA_DESTROY(protoent, &td_snap); + TEST_DATA_DESTROY(protoent, &td); + + return (rv); +} + +#define SNAPSHOT_FILE "snapshot_proto" + +ATF_TC_WITHOUT_HEAD(build_snapshot); +ATF_TC_BODY(build_snapshot, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); +} + +ATF_TC_WITHOUT_HEAD(getprotoent); +ATF_TC_BODY(getprotoent, tc) +{ + + ATF_REQUIRE(run_tests(NULL, TEST_GETPROTOENT) == 0); +} + +ATF_TC_WITHOUT_HEAD(getprotoent_with_snapshot); +ATF_TC_BODY(getprotoent_with_snapshot, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETPROTOENT) == 0); +} + +ATF_TC_WITHOUT_HEAD(getprotoent_with_two_pass); +ATF_TC_BODY(getprotoent_with_two_pass, tc) +{ + + ATF_REQUIRE(run_tests(NULL, TEST_GETPROTOENT_2PASS) == 0); +} + +ATF_TC_WITHOUT_HEAD(getprotobyname); +ATF_TC_BODY(getprotobyname, tc) +{ + + ATF_REQUIRE(run_tests(NULL, TEST_GETPROTOBYNAME) == 0); +} + +ATF_TC_WITHOUT_HEAD(getprotobyname_with_snapshot); +ATF_TC_BODY(getprotobyname_with_snapshot, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETPROTOBYNAME) == 0); +} + +ATF_TC_WITHOUT_HEAD(getprotobynumber); +ATF_TC_BODY(getprotobynumber, tc) +{ + + ATF_REQUIRE(run_tests(NULL, TEST_GETPROTOBYNUMBER) == 0); +} + +ATF_TC_WITHOUT_HEAD(getprotobynumber_with_snapshot); +ATF_TC_BODY(getprotobynumber_with_snapshot, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETPROTOBYNUMBER) == 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, build_snapshot); + ATF_TP_ADD_TC(tp, getprotoent); + ATF_TP_ADD_TC(tp, getprotoent_with_snapshot); + ATF_TP_ADD_TC(tp, getprotoent_with_two_pass); + ATF_TP_ADD_TC(tp, getprotobyname); + ATF_TP_ADD_TC(tp, getprotobyname_with_snapshot); + ATF_TP_ADD_TC(tp, getprotobynumber); + ATF_TP_ADD_TC(tp, getprotobynumber_with_snapshot); + + return (atf_no_error()); +} Property changes on: user/ngie/stable-10-libnv/lib/libc/tests/nss/getproto_test.c ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: user/ngie/stable-10-libnv/lib/libc/tests/nss/getpw_test.c =================================================================== --- user/ngie/stable-10-libnv/lib/libc/tests/nss/getpw_test.c (nonexistent) +++ user/ngie/stable-10-libnv/lib/libc/tests/nss/getpw_test.c (revision 292857) @@ -0,0 +1,530 @@ +/*- + * Copyright (c) 2006 Michael Bushkov + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include + +#include + +#include "testutil.h" + +enum test_methods { + TEST_GETPWENT, + TEST_GETPWNAM, + TEST_GETPWUID, + TEST_GETPWENT_2PASS, + TEST_BUILD_SNAPSHOT +}; + +static enum test_methods method = TEST_BUILD_SNAPSHOT; + +DECLARE_TEST_DATA(passwd) +DECLARE_TEST_FILE_SNAPSHOT(passwd) +DECLARE_1PASS_TEST(passwd) +DECLARE_2PASS_TEST(passwd) + +static void clone_passwd(struct passwd *, struct passwd const *); +static int compare_passwd(struct passwd *, struct passwd *, void *); +static void free_passwd(struct passwd *); + +static void sdump_passwd(struct passwd *, char *, size_t); +static void dump_passwd(struct passwd *); + +static int passwd_read_snapshot_func(struct passwd *, char *); + +static int passwd_check_ambiguity(struct passwd_test_data *, struct passwd *); +static int passwd_fill_test_data(struct passwd_test_data *); +static int passwd_test_correctness(struct passwd *, void *); +static int passwd_test_getpwnam(struct passwd *, void *); +static int passwd_test_getpwuid(struct passwd *, void *); +static int passwd_test_getpwent(struct passwd *, void *); + +IMPLEMENT_TEST_DATA(passwd) +IMPLEMENT_TEST_FILE_SNAPSHOT(passwd) +IMPLEMENT_1PASS_TEST(passwd) +IMPLEMENT_2PASS_TEST(passwd) + +static void +clone_passwd(struct passwd *dest, struct passwd const *src) +{ + ATF_REQUIRE(dest != NULL); + ATF_REQUIRE(src != NULL); + + memcpy(dest, src, sizeof(struct passwd)); + if (src->pw_name != NULL) + dest->pw_name = strdup(src->pw_name); + if (src->pw_passwd != NULL) + dest->pw_passwd = strdup(src->pw_passwd); + if (src->pw_class != NULL) + dest->pw_class = strdup(src->pw_class); + if (src->pw_gecos != NULL) + dest->pw_gecos = strdup(src->pw_gecos); + if (src->pw_dir != NULL) + dest->pw_dir = strdup(src->pw_dir); + if (src->pw_shell != NULL) + dest->pw_shell = strdup(dest->pw_shell); +} + +static int +compare_passwd(struct passwd *pwd1, struct passwd *pwd2, void *mdata) +{ + ATF_REQUIRE(pwd1 != NULL); + ATF_REQUIRE(pwd2 != NULL); + + if (pwd1 == pwd2) + return (0); + + if (pwd1->pw_uid != pwd2->pw_uid || + pwd1->pw_gid != pwd2->pw_gid || + pwd1->pw_change != pwd2->pw_change || + pwd1->pw_expire != pwd2->pw_expire || + pwd1->pw_fields != pwd2->pw_fields || + strcmp(pwd1->pw_name, pwd2->pw_name) != 0 || + strcmp(pwd1->pw_passwd, pwd2->pw_passwd) != 0 || + strcmp(pwd1->pw_class, pwd2->pw_class) != 0 || + strcmp(pwd1->pw_gecos, pwd2->pw_gecos) != 0 || + strcmp(pwd1->pw_dir, pwd2->pw_dir) != 0 || + strcmp(pwd1->pw_shell, pwd2->pw_shell) != 0) + return (-1); + else + return (0); +} + +static void +free_passwd(struct passwd *pwd) +{ + free(pwd->pw_name); + free(pwd->pw_passwd); + free(pwd->pw_class); + free(pwd->pw_gecos); + free(pwd->pw_dir); + free(pwd->pw_shell); +} + +static void +sdump_passwd(struct passwd *pwd, char *buffer, size_t buflen) +{ + snprintf(buffer, buflen, "%s:%s:%d:%d:%jd:%s:%s:%s:%s:%jd:%d", + pwd->pw_name, pwd->pw_passwd, pwd->pw_uid, pwd->pw_gid, + (uintmax_t)pwd->pw_change, pwd->pw_class, pwd->pw_gecos, + pwd->pw_dir, pwd->pw_shell, (uintmax_t)pwd->pw_expire, + pwd->pw_fields); +} + +static void +dump_passwd(struct passwd *pwd) +{ + if (pwd != NULL) { + char buffer[2048]; + sdump_passwd(pwd, buffer, sizeof(buffer)); + printf("%s\n", buffer); + } else + printf("(null)\n"); +} + +static int +passwd_read_snapshot_func(struct passwd *pwd, char *line) +{ + char *s, *ps, *ts; + int i; + +#ifdef DEBUG + printf("1 line read from snapshot:\n%s\n", line); +#endif + + i = 0; + ps = line; + memset(pwd, 0, sizeof(struct passwd)); + while ((s = strsep(&ps, ":")) != NULL) { + switch (i) { + case 0: + pwd->pw_name = strdup(s); + ATF_REQUIRE(pwd->pw_name != NULL); + break; + case 1: + pwd->pw_passwd = strdup(s); + ATF_REQUIRE(pwd->pw_passwd != NULL); + break; + case 2: + pwd->pw_uid = (uid_t)strtol(s, &ts, 10); + if (*ts != '\0') + goto fin; + break; + case 3: + pwd->pw_gid = (gid_t)strtol(s, &ts, 10); + if (*ts != '\0') + goto fin; + break; + case 4: + pwd->pw_change = (time_t)strtol(s, &ts, 10); + if (*ts != '\0') + goto fin; + break; + case 5: + pwd->pw_class = strdup(s); + ATF_REQUIRE(pwd->pw_class != NULL); + break; + case 6: + pwd->pw_gecos = strdup(s); + ATF_REQUIRE(pwd->pw_gecos != NULL); + break; + case 7: + pwd->pw_dir = strdup(s); + ATF_REQUIRE(pwd->pw_dir != NULL); + break; + case 8: + pwd->pw_shell = strdup(s); + ATF_REQUIRE(pwd->pw_shell != NULL); + break; + case 9: + pwd->pw_expire = (time_t)strtol(s, &ts, 10); + if (*ts != '\0') + goto fin; + break; + case 10: + pwd->pw_fields = (int)strtol(s, &ts, 10); + if (*ts != '\0') + goto fin; + break; + default: + break; + } + ++i; + } + +fin: + if (i != 11) { + free_passwd(pwd); + memset(pwd, 0, sizeof(struct passwd)); + return (-1); + } + + return (0); +} + +static int +passwd_fill_test_data(struct passwd_test_data *td) +{ + struct passwd *pwd; + + setpassent(1); + while ((pwd = getpwent()) != NULL) { + if (passwd_test_correctness(pwd, NULL) == 0) + TEST_DATA_APPEND(passwd, td, pwd); + else + return (-1); + } + endpwent(); + + return (0); +} + +static int +passwd_test_correctness(struct passwd *pwd, void *mdata) +{ + +#ifdef DEBUG + printf("testing correctness with the following data:\n"); + dump_passwd(pwd); +#endif + + if (pwd == NULL) + return (-1); + + if (pwd->pw_name == NULL) + goto errfin; + + if (pwd->pw_passwd == NULL) + goto errfin; + + if (pwd->pw_class == NULL) + goto errfin; + + if (pwd->pw_gecos == NULL) + goto errfin; + + if (pwd->pw_dir == NULL) + goto errfin; + + if (pwd->pw_shell == NULL) + goto errfin; + +#ifdef DEBUG + printf("correct\n"); +#endif + + return (0); +errfin: +#ifdef DEBUG + printf("incorrect\n"); +#endif + + return (-1); +} + +/* passwd_check_ambiguity() is needed here because when doing the getpwent() + * calls sequence, records from different nsswitch sources can be different, + * though having the same pw_name/pw_uid */ +static int +passwd_check_ambiguity(struct passwd_test_data *td, struct passwd *pwd) +{ + + return (TEST_DATA_FIND(passwd, td, pwd, compare_passwd, + NULL) != NULL ? 0 : -1); +} + +static int +passwd_test_getpwnam(struct passwd *pwd_model, void *mdata) +{ + struct passwd *pwd; + +#ifdef DEBUG + printf("testing getpwnam() with the following data:\n"); + dump_passwd(pwd_model); +#endif + + pwd = getpwnam(pwd_model->pw_name); + if (passwd_test_correctness(pwd, NULL) != 0) + goto errfin; + + if ((compare_passwd(pwd, pwd_model, NULL) != 0) && + (passwd_check_ambiguity((struct passwd_test_data *)mdata, pwd) + !=0)) + goto errfin; + +#ifdef DEBUG + printf("ok\n"); +#endif + return (0); + +errfin: +#ifdef DEBUG + printf("not ok\n"); +#endif + return (-1); +} + +static int +passwd_test_getpwuid(struct passwd *pwd_model, void *mdata) +{ + struct passwd *pwd; + +#ifdef DEBUG + printf("testing getpwuid() with the following data...\n"); + dump_passwd(pwd_model); +#endif + + pwd = getpwuid(pwd_model->pw_uid); + if ((passwd_test_correctness(pwd, NULL) != 0) || + ((compare_passwd(pwd, pwd_model, NULL) != 0) && + (passwd_check_ambiguity((struct passwd_test_data *)mdata, pwd) + != 0))) { +#ifdef DEBUG + printf("not ok\n"); +#endif + return (-1); + } else { +#ifdef DEBUG + printf("ok\n"); +#endif + return (0); + } +} + +static int +passwd_test_getpwent(struct passwd *pwd, void *mdata) +{ + /* Only correctness can be checked when doing 1-pass test for + * getpwent(). */ + return (passwd_test_correctness(pwd, NULL)); +} + +static int +run_tests(const char *snapshot_file, enum test_methods method) +{ + struct passwd_test_data td, td_snap, td_2pass; + int rv; + + TEST_DATA_INIT(passwd, &td, clone_passwd, free_passwd); + TEST_DATA_INIT(passwd, &td_snap, clone_passwd, free_passwd); + if (snapshot_file != NULL) { + if (access(snapshot_file, W_OK | R_OK) != 0) { + if (errno == ENOENT) + method = TEST_BUILD_SNAPSHOT; + else { + printf("can't access the file %s\n", + snapshot_file); + rv = -1; + goto fin; + } + } else { + if (method == TEST_BUILD_SNAPSHOT) { + rv = 0; + goto fin; + } + + TEST_SNAPSHOT_FILE_READ(passwd, snapshot_file, + &td_snap, passwd_read_snapshot_func); + } + } + + rv = passwd_fill_test_data(&td); + if (rv == -1) + return (-1); + + switch (method) { + case TEST_GETPWNAM: + if (snapshot_file == NULL) + rv = DO_1PASS_TEST(passwd, &td, + passwd_test_getpwnam, (void *)&td); + else + rv = DO_1PASS_TEST(passwd, &td_snap, + passwd_test_getpwnam, (void *)&td_snap); + break; + case TEST_GETPWUID: + if (snapshot_file == NULL) + rv = DO_1PASS_TEST(passwd, &td, + passwd_test_getpwuid, (void *)&td); + else + rv = DO_1PASS_TEST(passwd, &td_snap, + passwd_test_getpwuid, (void *)&td_snap); + break; + case TEST_GETPWENT: + if (snapshot_file == NULL) + rv = DO_1PASS_TEST(passwd, &td, passwd_test_getpwent, + (void *)&td); + else + rv = DO_2PASS_TEST(passwd, &td, &td_snap, + compare_passwd, NULL); + break; + case TEST_GETPWENT_2PASS: + TEST_DATA_INIT(passwd, &td_2pass, clone_passwd, free_passwd); + rv = passwd_fill_test_data(&td_2pass); + if (rv != -1) + rv = DO_2PASS_TEST(passwd, &td, &td_2pass, + compare_passwd, NULL); + TEST_DATA_DESTROY(passwd, &td_2pass); + break; + case TEST_BUILD_SNAPSHOT: + if (snapshot_file != NULL) + rv = TEST_SNAPSHOT_FILE_WRITE(passwd, snapshot_file, + &td, sdump_passwd); + break; + default: + rv = 0; + break; + } + +fin: + TEST_DATA_DESTROY(passwd, &td_snap); + TEST_DATA_DESTROY(passwd, &td); + + return (rv); +} + +#define SNAPSHOT_FILE "snapshot_pwd" + +ATF_TC_WITHOUT_HEAD(build_snapshot); +ATF_TC_BODY(build_snapshot, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); +} + +ATF_TC_WITHOUT_HEAD(getpwent); +ATF_TC_BODY(getpwent, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETPWENT) == 0); +} + +ATF_TC_WITHOUT_HEAD(getpwent_with_snapshot); +ATF_TC_BODY(getpwent_with_snapshot, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETPWENT) == 0); +} + +ATF_TC_WITHOUT_HEAD(getpwent_with_two_pass); +ATF_TC_BODY(getpwent_with_two_pass, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETPWENT_2PASS) == 0); +} + +ATF_TC_WITHOUT_HEAD(getpwnam); +ATF_TC_BODY(getpwnam, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETPWNAM) == 0); +} + +ATF_TC_WITHOUT_HEAD(getpwnam_with_snapshot); +ATF_TC_BODY(getpwnam_with_snapshot, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETPWNAM) == 0); +} + +ATF_TC_WITHOUT_HEAD(getpwuid); +ATF_TC_BODY(getpwuid, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETPWUID) == 0); +} + +ATF_TC_WITHOUT_HEAD(getpwuid_with_snapshot); +ATF_TC_BODY(getpwuid_with_snapshot, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETPWUID) == 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, build_snapshot); + ATF_TP_ADD_TC(tp, getpwent); + ATF_TP_ADD_TC(tp, getpwent_with_snapshot); + ATF_TP_ADD_TC(tp, getpwent_with_two_pass); + ATF_TP_ADD_TC(tp, getpwnam); + ATF_TP_ADD_TC(tp, getpwnam_with_snapshot); + ATF_TP_ADD_TC(tp, getpwuid); + ATF_TP_ADD_TC(tp, getpwuid_with_snapshot); + + return (atf_no_error()); +} Property changes on: user/ngie/stable-10-libnv/lib/libc/tests/nss/getpw_test.c ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: user/ngie/stable-10-libnv/lib/libc/tests/nss/getrpc_test.c =================================================================== --- user/ngie/stable-10-libnv/lib/libc/tests/nss/getrpc_test.c (nonexistent) +++ user/ngie/stable-10-libnv/lib/libc/tests/nss/getrpc_test.c (revision 292857) @@ -0,0 +1,560 @@ +/*- + * Copyright (c) 2006 Michael Bushkov + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "testutil.h" + +enum test_methods { + TEST_GETRPCENT, + TEST_GETRPCBYNAME, + TEST_GETRPCBYNUMBER, + TEST_GETRPCENT_2PASS, + TEST_BUILD_SNAPSHOT +}; + +DECLARE_TEST_DATA(rpcent) +DECLARE_TEST_FILE_SNAPSHOT(rpcent) +DECLARE_1PASS_TEST(rpcent) +DECLARE_2PASS_TEST(rpcent) + +static void clone_rpcent(struct rpcent *, struct rpcent const *); +static int compare_rpcent(struct rpcent *, struct rpcent *, void *); +static void dump_rpcent(struct rpcent *); +static void free_rpcent(struct rpcent *); + +static void sdump_rpcent(struct rpcent *, char *, size_t); +static int rpcent_read_snapshot_func(struct rpcent *, char *); + +static int rpcent_check_ambiguity(struct rpcent_test_data *, + struct rpcent *); +static int rpcent_fill_test_data(struct rpcent_test_data *); +static int rpcent_test_correctness(struct rpcent *, void *); +static int rpcent_test_getrpcbyname(struct rpcent *, void *); +static int rpcent_test_getrpcbynumber(struct rpcent *, void *); +static int rpcent_test_getrpcent(struct rpcent *, void *); + +static void usage(void) __attribute__((__noreturn__)); + +IMPLEMENT_TEST_DATA(rpcent) +IMPLEMENT_TEST_FILE_SNAPSHOT(rpcent) +IMPLEMENT_1PASS_TEST(rpcent) +IMPLEMENT_2PASS_TEST(rpcent) + +static void +clone_rpcent(struct rpcent *dest, struct rpcent const *src) +{ + ATF_REQUIRE(dest != NULL); + ATF_REQUIRE(src != NULL); + + char **cp; + int aliases_num; + + memset(dest, 0, sizeof(struct rpcent)); + + if (src->r_name != NULL) { + dest->r_name = strdup(src->r_name); + ATF_REQUIRE(dest->r_name != NULL); + } + + dest->r_number = src->r_number; + + if (src->r_aliases != NULL) { + aliases_num = 0; + for (cp = src->r_aliases; *cp; ++cp) + ++aliases_num; + + dest->r_aliases = calloc(1, (aliases_num + 1) * sizeof(char *)); + ATF_REQUIRE(dest->r_aliases != NULL); + + for (cp = src->r_aliases; *cp; ++cp) { + dest->r_aliases[cp - src->r_aliases] = strdup(*cp); + ATF_REQUIRE(dest->r_aliases[cp - src->r_aliases] != NULL); + } + } +} + +static void +free_rpcent(struct rpcent *rpc) +{ + char **cp; + + ATF_REQUIRE(rpc != NULL); + + free(rpc->r_name); + + for (cp = rpc->r_aliases; *cp; ++cp) + free(*cp); + free(rpc->r_aliases); +} + +static int +compare_rpcent(struct rpcent *rpc1, struct rpcent *rpc2, void *mdata) +{ + char **c1, **c2; + + if (rpc1 == rpc2) + return 0; + + if ((rpc1 == NULL) || (rpc2 == NULL)) + goto errfin; + + if ((strcmp(rpc1->r_name, rpc2->r_name) != 0) || + (rpc1->r_number != rpc2->r_number)) + goto errfin; + + c1 = rpc1->r_aliases; + c2 = rpc2->r_aliases; + + if ((rpc1->r_aliases == NULL) || (rpc2->r_aliases == NULL)) + goto errfin; + + for (;*c1 && *c2; ++c1, ++c2) + if (strcmp(*c1, *c2) != 0) + goto errfin; + + if ((*c1 != '\0') || (*c2 != '\0')) + goto errfin; + + return 0; + +errfin: + if (mdata == NULL) { + printf("following structures are not equal:\n"); + dump_rpcent(rpc1); + dump_rpcent(rpc2); + } + + return (-1); +} + +static void +sdump_rpcent(struct rpcent *rpc, char *buffer, size_t buflen) +{ + char **cp; + int written; + + written = snprintf(buffer, buflen, "%s %d", + rpc->r_name, rpc->r_number); + buffer += written; + if (written > buflen) + return; + buflen -= written; + + if (rpc->r_aliases != NULL) { + if (*(rpc->r_aliases) != '\0') { + for (cp = rpc->r_aliases; *cp; ++cp) { + written = snprintf(buffer, buflen, " %s",*cp); + buffer += written; + if (written > buflen) + return; + buflen -= written; + + if (buflen == 0) + return; + } + } else + snprintf(buffer, buflen, " noaliases"); + } else + snprintf(buffer, buflen, " (null)"); +} + +static int +rpcent_read_snapshot_func(struct rpcent *rpc, char *line) +{ + StringList *sl; + char *s, *ps, *ts; + int i; + + printf("1 line read from snapshot:\n%s\n", line); + + i = 0; + sl = NULL; + ps = line; + memset(rpc, 0, sizeof(struct rpcent)); + while ((s = strsep(&ps, " ")) != NULL) { + switch (i) { + case 0: + rpc->r_name = strdup(s); + ATF_REQUIRE(rpc->r_name != NULL); + break; + + case 1: + rpc->r_number = (int)strtol(s, &ts, 10); + if (*ts != '\0') { + free(rpc->r_name); + return (-1); + } + break; + + default: + if (sl == NULL) { + if (strcmp(s, "(null)") == 0) + return (0); + + sl = sl_init(); + ATF_REQUIRE(sl != NULL); + + if (strcmp(s, "noaliases") != 0) { + ts = strdup(s); + ATF_REQUIRE(ts != NULL); + sl_add(sl, ts); + } + } else { + ts = strdup(s); + ATF_REQUIRE(ts != NULL); + sl_add(sl, ts); + } + break; + } + i++; + } + + if (i < 3) { + free(rpc->r_name); + memset(rpc, 0, sizeof(struct rpcent)); + return (-1); + } + + sl_add(sl, NULL); + rpc->r_aliases = sl->sl_str; + + /* NOTE: is it a dirty hack or not? */ + free(sl); + return (0); +} + +static void +dump_rpcent(struct rpcent *result) +{ + if (result != NULL) { + char buffer[1024]; + sdump_rpcent(result, buffer, sizeof(buffer)); + printf("%s\n", buffer); + } else + printf("(null)\n"); +} + +static int +rpcent_fill_test_data(struct rpcent_test_data *td) +{ + struct rpcent *rpc; + + setrpcent(1); + while ((rpc = getrpcent()) != NULL) { + if (rpcent_test_correctness(rpc, NULL) == 0) + TEST_DATA_APPEND(rpcent, td, rpc); + else + return (-1); + } + endrpcent(); + + return (0); +} + +static int +rpcent_test_correctness(struct rpcent *rpc, void *mdata) +{ + + printf("testing correctness with the following data:\n"); + dump_rpcent(rpc); + + if (rpc == NULL) + goto errfin; + + if (rpc->r_name == NULL) + goto errfin; + + if (rpc->r_number < 0) + goto errfin; + + if (rpc->r_aliases == NULL) + goto errfin; + + printf("correct\n"); + + return (0); +errfin: + printf("incorrect\n"); + + return (-1); +} + +/* rpcent_check_ambiguity() is needed when one port+rpc is associated with + * more than one peice (these cases are usually marked as PROBLEM in + * /etc/peices. This functions is needed also when one peice+rpc is + * associated with several ports. We have to check all the rpcent structures + * to make sure that rpc really exists and correct */ +static int +rpcent_check_ambiguity(struct rpcent_test_data *td, struct rpcent *rpc) +{ + + return (TEST_DATA_FIND(rpcent, td, rpc, compare_rpcent, + NULL) != NULL ? 0 : -1); +} + +static int +rpcent_test_getrpcbyname(struct rpcent *rpc_model, void *mdata) +{ + char **alias; + struct rpcent *rpc; + + printf("testing getrpcbyname() with the following data:\n"); + dump_rpcent(rpc_model); + + rpc = getrpcbyname(rpc_model->r_name); + if (rpcent_test_correctness(rpc, NULL) != 0) + goto errfin; + + if ((compare_rpcent(rpc, rpc_model, NULL) != 0) && + (rpcent_check_ambiguity((struct rpcent_test_data *)mdata, rpc) + !=0)) + goto errfin; + + for (alias = rpc_model->r_aliases; *alias; ++alias) { + rpc = getrpcbyname(*alias); + + if (rpcent_test_correctness(rpc, NULL) != 0) + goto errfin; + + if ((compare_rpcent(rpc, rpc_model, NULL) != 0) && + (rpcent_check_ambiguity( + (struct rpcent_test_data *)mdata, rpc) != 0)) + goto errfin; + } + + printf("ok\n"); + return (0); + +errfin: + printf("not ok\n"); + + return (-1); +} + +static int +rpcent_test_getrpcbynumber(struct rpcent *rpc_model, void *mdata) +{ + struct rpcent *rpc; + + printf("testing getrpcbyport() with the following data...\n"); + dump_rpcent(rpc_model); + + rpc = getrpcbynumber(rpc_model->r_number); + if (rpcent_test_correctness(rpc, NULL) != 0 || + (compare_rpcent(rpc, rpc_model, NULL) != 0 && + rpcent_check_ambiguity((struct rpcent_test_data *)mdata, rpc) + != 0)) { + printf("not ok\n"); + return (-1); + } else { + printf("ok\n"); + return (0); + } +} + +static int +rpcent_test_getrpcent(struct rpcent *rpc, void *mdata) +{ + + /* + * Only correctness can be checked when doing 1-pass test for + * getrpcent(). + */ + return (rpcent_test_correctness(rpc, NULL)); +} + +int +run_tests(const char *snapshot_file, enum test_methods method) +{ + struct rpcent_test_data td, td_snap, td_2pass; + int rv; + + TEST_DATA_INIT(rpcent, &td, clone_rpcent, free_rpcent); + TEST_DATA_INIT(rpcent, &td_snap, clone_rpcent, free_rpcent); + if (snapshot_file != NULL) { + if (access(snapshot_file, W_OK | R_OK) != 0) { + if (errno == ENOENT) + method = TEST_BUILD_SNAPSHOT; + else { + printf("can't access the file %s\n", + snapshot_file); + + rv = -1; + goto fin; + } + } else { + if (method == TEST_BUILD_SNAPSHOT) { + rv = 0; + goto fin; + } + + TEST_SNAPSHOT_FILE_READ(rpcent, snapshot_file, + &td_snap, rpcent_read_snapshot_func); + } + } + + rv = rpcent_fill_test_data(&td); + if (rv == -1) + return (-1); + switch (method) { + case TEST_GETRPCBYNAME: + if (snapshot_file == NULL) + rv = DO_1PASS_TEST(rpcent, &td, + rpcent_test_getrpcbyname, (void *)&td); + else + rv = DO_1PASS_TEST(rpcent, &td_snap, + rpcent_test_getrpcbyname, (void *)&td_snap); + break; + case TEST_GETRPCBYNUMBER: + if (snapshot_file == NULL) + rv = DO_1PASS_TEST(rpcent, &td, + rpcent_test_getrpcbynumber, (void *)&td); + else + rv = DO_1PASS_TEST(rpcent, &td_snap, + rpcent_test_getrpcbynumber, (void *)&td_snap); + break; + case TEST_GETRPCENT: + if (snapshot_file == NULL) + rv = DO_1PASS_TEST(rpcent, &td, rpcent_test_getrpcent, + (void *)&td); + else + rv = DO_2PASS_TEST(rpcent, &td, &td_snap, + compare_rpcent, NULL); + break; + case TEST_GETRPCENT_2PASS: + TEST_DATA_INIT(rpcent, &td_2pass, clone_rpcent, free_rpcent); + rv = rpcent_fill_test_data(&td_2pass); + if (rv != -1) + rv = DO_2PASS_TEST(rpcent, &td, &td_2pass, + compare_rpcent, NULL); + TEST_DATA_DESTROY(rpcent, &td_2pass); + break; + case TEST_BUILD_SNAPSHOT: + if (snapshot_file != NULL) + rv = TEST_SNAPSHOT_FILE_WRITE(rpcent, snapshot_file, &td, + sdump_rpcent); + break; + default: + rv = 0; + break; + } + +fin: + TEST_DATA_DESTROY(rpcent, &td_snap); + TEST_DATA_DESTROY(rpcent, &td); + + return (rv); +} + +#define SNAPSHOT_FILE "snapshot_rpc" + +ATF_TC_WITHOUT_HEAD(build_snapshot); +ATF_TC_BODY(build_snapshot, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); +} + +ATF_TC_WITHOUT_HEAD(getrpcbyname); +ATF_TC_BODY(getrpcbyname, tc) +{ + + ATF_REQUIRE(run_tests(NULL, TEST_GETRPCBYNAME) == 0); +} + +ATF_TC_WITHOUT_HEAD(getrpcbyname_with_snapshot); +ATF_TC_BODY(getrpcbyname_with_snapshot, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETRPCBYNAME) == 0); +} + +ATF_TC_WITHOUT_HEAD(getrpcbynumber); +ATF_TC_BODY(getrpcbynumber, tc) +{ + + ATF_REQUIRE(run_tests(NULL, TEST_GETRPCBYNUMBER) == 0); +} + +ATF_TC_WITHOUT_HEAD(getrpcbynumber_with_snapshot); +ATF_TC_BODY(getrpcbynumber_with_snapshot, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETRPCBYNUMBER) == 0); +} + +ATF_TC_WITHOUT_HEAD(getrpcbyent); +ATF_TC_BODY(getrpcbyent, tc) +{ + + ATF_REQUIRE(run_tests(NULL, TEST_GETRPCENT) == 0); +} + +ATF_TC_WITHOUT_HEAD(getrpcbyent_with_snapshot); +ATF_TC_BODY(getrpcbyent_with_snapshot, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETRPCENT) == 0); +} + +ATF_TC_WITHOUT_HEAD(getrpcbyent_with_two_pass); +ATF_TC_BODY(getrpcbyent_with_two_pass, tc) +{ + + ATF_REQUIRE(run_tests(NULL, TEST_GETRPCENT_2PASS) == 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, build_snapshot); + ATF_TP_ADD_TC(tp, getrpcbyname); + ATF_TP_ADD_TC(tp, getrpcbyname_with_snapshot); + ATF_TP_ADD_TC(tp, getrpcbynumber); + ATF_TP_ADD_TC(tp, getrpcbynumber_with_snapshot); + ATF_TP_ADD_TC(tp, getrpcbyent); + ATF_TP_ADD_TC(tp, getrpcbyent_with_snapshot); + ATF_TP_ADD_TC(tp, getrpcbyent_with_two_pass); + + return (atf_no_error()); +} Property changes on: user/ngie/stable-10-libnv/lib/libc/tests/nss/getrpc_test.c ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: user/ngie/stable-10-libnv/lib/libc/tests/nss/getserv_test.c =================================================================== --- user/ngie/stable-10-libnv/lib/libc/tests/nss/getserv_test.c (nonexistent) +++ user/ngie/stable-10-libnv/lib/libc/tests/nss/getserv_test.c (revision 292857) @@ -0,0 +1,570 @@ +/*- + * Copyright (c) 2006 Michael Bushkov + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "testutil.h" + +enum test_methods { + TEST_GETSERVENT, + TEST_GETSERVBYNAME, + TEST_GETSERVBYPORT, + TEST_GETSERVENT_2PASS, + TEST_BUILD_SNAPSHOT +}; + +DECLARE_TEST_DATA(servent) +DECLARE_TEST_FILE_SNAPSHOT(servent) +DECLARE_1PASS_TEST(servent) +DECLARE_2PASS_TEST(servent) + +static void clone_servent(struct servent *, struct servent const *); +static int compare_servent(struct servent *, struct servent *, void *); +static void dump_servent(struct servent *); +static void free_servent(struct servent *); + +static void sdump_servent(struct servent *, char *, size_t); +static int servent_read_snapshot_func(struct servent *, char *); + +static int servent_check_ambiguity(struct servent_test_data *, + struct servent *); +static int servent_fill_test_data(struct servent_test_data *); +static int servent_test_correctness(struct servent *, void *); +static int servent_test_getservbyname(struct servent *, void *); +static int servent_test_getservbyport(struct servent *, void *); +static int servent_test_getservent(struct servent *, void *); + +IMPLEMENT_TEST_DATA(servent) +IMPLEMENT_TEST_FILE_SNAPSHOT(servent) +IMPLEMENT_1PASS_TEST(servent) +IMPLEMENT_2PASS_TEST(servent) + +static void +clone_servent(struct servent *dest, struct servent const *src) +{ + ATF_REQUIRE(dest != NULL); + ATF_REQUIRE(src != NULL); + + char **cp; + int aliases_num; + + memset(dest, 0, sizeof(struct servent)); + + if (src->s_name != NULL) { + dest->s_name = strdup(src->s_name); + ATF_REQUIRE(dest->s_name != NULL); + } + + if (src->s_proto != NULL) { + dest->s_proto = strdup(src->s_proto); + ATF_REQUIRE(dest->s_proto != NULL); + } + dest->s_port = src->s_port; + + if (src->s_aliases != NULL) { + aliases_num = 0; + for (cp = src->s_aliases; *cp; ++cp) + ++aliases_num; + + dest->s_aliases = calloc(1, (aliases_num + 1) * sizeof(char *)); + ATF_REQUIRE(dest->s_aliases != NULL); + + for (cp = src->s_aliases; *cp; ++cp) { + dest->s_aliases[cp - src->s_aliases] = strdup(*cp); + ATF_REQUIRE(dest->s_aliases[cp - src->s_aliases] != NULL); + } + } +} + +static void +free_servent(struct servent *serv) +{ + char **cp; + + ATF_REQUIRE(serv != NULL); + + free(serv->s_name); + free(serv->s_proto); + + for (cp = serv->s_aliases; *cp; ++cp) + free(*cp); + free(serv->s_aliases); +} + +static int +compare_servent(struct servent *serv1, struct servent *serv2, void *mdata) +{ + char **c1, **c2; + + if (serv1 == serv2) + return 0; + + if ((serv1 == NULL) || (serv2 == NULL)) + goto errfin; + + if ((strcmp(serv1->s_name, serv2->s_name) != 0) || + (strcmp(serv1->s_proto, serv2->s_proto) != 0) || + (serv1->s_port != serv2->s_port)) + goto errfin; + + c1 = serv1->s_aliases; + c2 = serv2->s_aliases; + + if ((serv1->s_aliases == NULL) || (serv2->s_aliases == NULL)) + goto errfin; + + for (;*c1 && *c2; ++c1, ++c2) + if (strcmp(*c1, *c2) != 0) + goto errfin; + + if ((*c1 != '\0') || (*c2 != '\0')) + goto errfin; + + return 0; + +errfin: + if (mdata == NULL) { + printf("following structures are not equal:\n"); + dump_servent(serv1); + dump_servent(serv2); + } + + return (-1); +} + +static void +sdump_servent(struct servent *serv, char *buffer, size_t buflen) +{ + char **cp; + int written; + + written = snprintf(buffer, buflen, "%s %d %s", + serv->s_name, ntohs(serv->s_port), serv->s_proto); + buffer += written; + if (written > buflen) + return; + buflen -= written; + + if (serv->s_aliases != NULL) { + if (*(serv->s_aliases) != '\0') { + for (cp = serv->s_aliases; *cp; ++cp) { + written = snprintf(buffer, buflen, " %s",*cp); + buffer += written; + if (written > buflen) + return; + buflen -= written; + + if (buflen == 0) + return; + } + } else + snprintf(buffer, buflen, " noaliases"); + } else + snprintf(buffer, buflen, " (null)"); +} + +static int +servent_read_snapshot_func(struct servent *serv, char *line) +{ + StringList *sl; + char *s, *ps, *ts; + int i; + + printf("1 line read from snapshot:\n%s\n", line); + + i = 0; + sl = NULL; + ps = line; + memset(serv, 0, sizeof(struct servent)); + while ( (s = strsep(&ps, " ")) != NULL) { + switch (i) { + case 0: + serv->s_name = strdup(s); + ATF_REQUIRE(serv->s_name != NULL); + break; + + case 1: + serv->s_port = htons( + (int)strtol(s, &ts, 10)); + if (*ts != '\0') { + free(serv->s_name); + return (-1); + } + break; + + case 2: + serv->s_proto = strdup(s); + ATF_REQUIRE(serv->s_proto != NULL); + break; + + default: + if (sl == NULL) { + if (strcmp(s, "(null)") == 0) + return (0); + + sl = sl_init(); + ATF_REQUIRE(sl != NULL); + + if (strcmp(s, "noaliases") != 0) { + ts = strdup(s); + ATF_REQUIRE(ts != NULL); + sl_add(sl, ts); + } + } else { + ts = strdup(s); + ATF_REQUIRE(ts != NULL); + sl_add(sl, ts); + } + break; + } + ++i; + } + + if (i < 3) { + free(serv->s_name); + free(serv->s_proto); + memset(serv, 0, sizeof(struct servent)); + return (-1); + } + + sl_add(sl, NULL); + serv->s_aliases = sl->sl_str; + + /* NOTE: is it a dirty hack or not? */ + free(sl); + return (0); +} + +static void +dump_servent(struct servent *result) +{ + if (result != NULL) { + char buffer[1024]; + sdump_servent(result, buffer, sizeof(buffer)); + printf("%s\n", buffer); + } else + printf("(null)\n"); +} + +static int +servent_fill_test_data(struct servent_test_data *td) +{ + struct servent *serv; + + setservent(1); + while ((serv = getservent()) != NULL) { + if (servent_test_correctness(serv, NULL) == 0) + TEST_DATA_APPEND(servent, td, serv); + else + return (-1); + } + endservent(); + + return (0); +} + +static int +servent_test_correctness(struct servent *serv, void *mdata) +{ + printf("testing correctness with the following data:\n"); + dump_servent(serv); + + if (serv == NULL) + goto errfin; + + if (serv->s_name == NULL) + goto errfin; + + if (serv->s_proto == NULL) + goto errfin; + + if (ntohs(serv->s_port < 0)) + goto errfin; + + if (serv->s_aliases == NULL) + goto errfin; + + printf("correct\n"); + + return (0); +errfin: + printf("incorrect\n"); + + return (-1); +} + +/* servent_check_ambiguity() is needed when one port+proto is associated with + * more than one service (these cases are usually marked as PROBLEM in + * /etc/services. This functions is needed also when one service+proto is + * associated with several ports. We have to check all the servent structures + * to make sure that serv really exists and correct */ +static int +servent_check_ambiguity(struct servent_test_data *td, struct servent *serv) +{ + + return (TEST_DATA_FIND(servent, td, serv, compare_servent, + NULL) != NULL ? 0 : -1); +} + +static int +servent_test_getservbyname(struct servent *serv_model, void *mdata) +{ + char **alias; + struct servent *serv; + + printf("testing getservbyname() with the following data:\n"); + dump_servent(serv_model); + + serv = getservbyname(serv_model->s_name, serv_model->s_proto); + if (servent_test_correctness(serv, NULL) != 0) + goto errfin; + + if ((compare_servent(serv, serv_model, NULL) != 0) && + (servent_check_ambiguity((struct servent_test_data *)mdata, serv) + !=0)) + goto errfin; + + for (alias = serv_model->s_aliases; *alias; ++alias) { + serv = getservbyname(*alias, serv_model->s_proto); + + if (servent_test_correctness(serv, NULL) != 0) + goto errfin; + + if ((compare_servent(serv, serv_model, NULL) != 0) && + (servent_check_ambiguity( + (struct servent_test_data *)mdata, serv) != 0)) + goto errfin; + } + + printf("ok\n"); + return (0); + +errfin: + printf("not ok\n"); + + return (-1); +} + +static int +servent_test_getservbyport(struct servent *serv_model, void *mdata) +{ + struct servent *serv; + + printf("testing getservbyport() with the following data...\n"); + dump_servent(serv_model); + + serv = getservbyport(serv_model->s_port, serv_model->s_proto); + if ((servent_test_correctness(serv, NULL) != 0) || + ((compare_servent(serv, serv_model, NULL) != 0) && + (servent_check_ambiguity((struct servent_test_data *)mdata, serv) + != 0))) { + printf("not ok\n"); + return (-1); + } else { + printf("ok\n"); + return (0); + } +} + +static int +servent_test_getservent(struct servent *serv, void *mdata) +{ + /* Only correctness can be checked when doing 1-pass test for + * getservent(). */ + return (servent_test_correctness(serv, NULL)); +} + +int +run_tests(const char *snapshot_file, enum test_methods method) +{ + struct servent_test_data td, td_snap, td_2pass; + int rv; + + TEST_DATA_INIT(servent, &td, clone_servent, free_servent); + TEST_DATA_INIT(servent, &td_snap, clone_servent, free_servent); + if (snapshot_file != NULL) { + if (access(snapshot_file, W_OK | R_OK) != 0) { + if (errno == ENOENT) + method = TEST_BUILD_SNAPSHOT; + else { + printf("can't access the file %s\n", + snapshot_file); + + rv = -1; + goto fin; + } + } else { + if (method == TEST_BUILD_SNAPSHOT) { + rv = 0; + goto fin; + } + + TEST_SNAPSHOT_FILE_READ(servent, snapshot_file, + &td_snap, servent_read_snapshot_func); + } + } + + rv = servent_fill_test_data(&td); + if (rv == -1) + return (-1); + switch (method) { + case TEST_GETSERVBYNAME: + if (snapshot_file == NULL) + rv = DO_1PASS_TEST(servent, &td, + servent_test_getservbyname, (void *)&td); + else + rv = DO_1PASS_TEST(servent, &td_snap, + servent_test_getservbyname, (void *)&td_snap); + break; + case TEST_GETSERVBYPORT: + if (snapshot_file == NULL) + rv = DO_1PASS_TEST(servent, &td, + servent_test_getservbyport, (void *)&td); + else + rv = DO_1PASS_TEST(servent, &td_snap, + servent_test_getservbyport, (void *)&td_snap); + break; + case TEST_GETSERVENT: + if (snapshot_file == NULL) + rv = DO_1PASS_TEST(servent, &td, servent_test_getservent, + (void *)&td); + else + rv = DO_2PASS_TEST(servent, &td, &td_snap, + compare_servent, NULL); + break; + case TEST_GETSERVENT_2PASS: + TEST_DATA_INIT(servent, &td_2pass, clone_servent, free_servent); + rv = servent_fill_test_data(&td_2pass); + if (rv != -1) + rv = DO_2PASS_TEST(servent, &td, &td_2pass, + compare_servent, NULL); + TEST_DATA_DESTROY(servent, &td_2pass); + break; + case TEST_BUILD_SNAPSHOT: + if (snapshot_file != NULL) + rv = TEST_SNAPSHOT_FILE_WRITE(servent, snapshot_file, &td, + sdump_servent); + break; + default: + rv = 0; + break; + } + +fin: + TEST_DATA_DESTROY(servent, &td_snap); + TEST_DATA_DESTROY(servent, &td); + + return (rv); +} + +#define SNAPSHOT_FILE "snapshot_serv" + +ATF_TC_WITHOUT_HEAD(build_snapshot); +ATF_TC_BODY(build_snapshot, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); +} + +ATF_TC_WITHOUT_HEAD(getservbyname); +ATF_TC_BODY(getservbyname, tc) +{ + + ATF_REQUIRE(run_tests(NULL, TEST_GETSERVBYNAME) == 0); +} + +ATF_TC_WITHOUT_HEAD(getservbyname_with_snapshot); +ATF_TC_BODY(getservbyname_with_snapshot, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETSERVBYNAME) == 0); +} + +ATF_TC_WITHOUT_HEAD(getservbyport); +ATF_TC_BODY(getservbyport, tc) +{ + + ATF_REQUIRE(run_tests(NULL, TEST_GETSERVBYPORT) == 0); +} + +ATF_TC_WITHOUT_HEAD(getservbyport_with_snapshot); +ATF_TC_BODY(getservbyport_with_snapshot, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETSERVBYPORT) == 0); +} + +ATF_TC_WITHOUT_HEAD(getservbyent); +ATF_TC_BODY(getservbyent, tc) +{ + + ATF_REQUIRE(run_tests(NULL, TEST_GETSERVENT) == 0); +} + +ATF_TC_WITHOUT_HEAD(getservbyent_with_snapshot); +ATF_TC_BODY(getservbyent_with_snapshot, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETSERVENT) == 0); +} + +ATF_TC_WITHOUT_HEAD(getservbyent_with_two_pass); +ATF_TC_BODY(getservbyent_with_two_pass, tc) +{ + + ATF_REQUIRE(run_tests(NULL, TEST_GETSERVENT_2PASS) == 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, build_snapshot); + ATF_TP_ADD_TC(tp, getservbyent); + ATF_TP_ADD_TC(tp, getservbyent_with_snapshot); + ATF_TP_ADD_TC(tp, getservbyent_with_two_pass); + ATF_TP_ADD_TC(tp, getservbyname); + ATF_TP_ADD_TC(tp, getservbyname_with_snapshot); + ATF_TP_ADD_TC(tp, getservbyport); + ATF_TP_ADD_TC(tp, getservbyport_with_snapshot); + + return (atf_no_error()); +} Property changes on: user/ngie/stable-10-libnv/lib/libc/tests/nss/getserv_test.c ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: user/ngie/stable-10-libnv/lib/libc/tests/nss/getusershell_test.c =================================================================== --- user/ngie/stable-10-libnv/lib/libc/tests/nss/getusershell_test.c (nonexistent) +++ user/ngie/stable-10-libnv/lib/libc/tests/nss/getusershell_test.c (revision 292857) @@ -0,0 +1,225 @@ +/*- + * Copyright (c) 2006 Michael Bushkov + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include + +#include + +#include "testutil.h" + +enum test_methods { + TEST_GETUSERSHELL, + TEST_BUILD_SNAPSHOT +}; + +struct usershell { + char *path; +}; + +static enum test_methods method = TEST_GETUSERSHELL; + +DECLARE_TEST_DATA(usershell) +DECLARE_TEST_FILE_SNAPSHOT(usershell) +DECLARE_2PASS_TEST(usershell) + +static void clone_usershell(struct usershell *, struct usershell const *); +static int compare_usershell(struct usershell *, struct usershell *, void *); +static void free_usershell(struct usershell *); + +static void sdump_usershell(struct usershell *, char *, size_t); +static void dump_usershell(struct usershell *); + +IMPLEMENT_TEST_DATA(usershell) +IMPLEMENT_TEST_FILE_SNAPSHOT(usershell) +IMPLEMENT_2PASS_TEST(usershell) + +static void +clone_usershell(struct usershell *dest, struct usershell const *src) +{ + assert(dest != NULL); + assert(src != NULL); + + if (src->path != NULL) { + dest->path = strdup(src->path); + assert(dest->path != NULL); + } +} + +static int +compare_usershell(struct usershell *us1, struct usershell *us2, void *mdata) +{ + int rv; + + assert(us1 != NULL); + assert(us2 != NULL); + + dump_usershell(us1); + dump_usershell(us2); + + if (us1 == us2) + return (0); + + rv = strcmp(us1->path, us2->path); + if (rv != 0) { + printf("following structures are not equal:\n"); + dump_usershell(us1); + dump_usershell(us2); + } + + return (rv); +} + +static void +free_usershell(struct usershell *us) +{ + free(us->path); +} + +static void +sdump_usershell(struct usershell *us, char *buffer, size_t buflen) +{ + snprintf(buffer, buflen, "%s", us->path); +} + +static void +dump_usershell(struct usershell *us) +{ + if (us != NULL) { + char buffer[2048]; + sdump_usershell(us, buffer, sizeof(buffer)); + printf("%s\n", buffer); + } else + printf("(null)\n"); +} + +static int +usershell_read_snapshot_func(struct usershell *us, char *line) +{ + + us->path = strdup(line); + ATF_REQUIRE(us->path != NULL); + + return (0); +} + +int +run_tests(const char *snapshot_file, enum test_methods method) +{ + struct usershell_test_data td, td_snap; + struct usershell ushell; + int rv; + + rv = 0; + + TEST_DATA_INIT(usershell, &td, clone_usershell, free_usershell); + TEST_DATA_INIT(usershell, &td_snap, clone_usershell, free_usershell); + + setusershell(); + while ((ushell.path = getusershell()) != NULL) { + printf("usershell found:\n"); + dump_usershell(&ushell); + TEST_DATA_APPEND(usershell, &td, &ushell); + } + endusershell(); + + if (snapshot_file != NULL) { + if (access(snapshot_file, W_OK | R_OK) != 0) { + if (errno == ENOENT) + method = TEST_BUILD_SNAPSHOT; + else { + printf("can't access the snapshot file %s\n", + snapshot_file); + + rv = -1; + goto fin; + } + } else { + rv = TEST_SNAPSHOT_FILE_READ(usershell, snapshot_file, + &td_snap, usershell_read_snapshot_func); + if (rv != 0) { + printf("error reading snapshot file\n"); + goto fin; + } + } + } + + switch (method) { + case TEST_GETUSERSHELL: + rv = DO_2PASS_TEST(usershell, &td, &td_snap, + compare_usershell, NULL); + break; + case TEST_BUILD_SNAPSHOT: + if (snapshot_file != NULL) { + rv = TEST_SNAPSHOT_FILE_WRITE(usershell, snapshot_file, + &td, sdump_usershell); + } + break; + default: + rv = 0; + break; + } + +fin: + TEST_DATA_DESTROY(usershell, &td_snap); + TEST_DATA_DESTROY(usershell, &td); + + return (rv); +} + +#define SNAPSHOT_FILE "snapshot_usershell" + +ATF_TC_WITHOUT_HEAD(getusershell_with_snapshot); +ATF_TC_BODY(getusershell_with_snapshot, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); +} + +ATF_TC_WITHOUT_HEAD(getusershell_with_two_pass); +ATF_TC_BODY(getusershell_with_two_pass, tc) +{ + + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_BUILD_SNAPSHOT) == 0); + ATF_REQUIRE(run_tests(SNAPSHOT_FILE, TEST_GETUSERSHELL) == 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, getusershell_with_snapshot); + ATF_TP_ADD_TC(tp, getusershell_with_two_pass); + + return (atf_no_error()); +} Property changes on: user/ngie/stable-10-libnv/lib/libc/tests/nss/getusershell_test.c ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: user/ngie/stable-10-libnv/lib/libc/tests/nss/testutil.h =================================================================== --- user/ngie/stable-10-libnv/lib/libc/tests/nss/testutil.h (nonexistent) +++ user/ngie/stable-10-libnv/lib/libc/tests/nss/testutil.h (revision 292857) @@ -0,0 +1,333 @@ +/*- + * Copyright (c) 2006 Michael Bushkov + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include + +#define DECLARE_TEST_DATA(ent) \ +struct ent##_entry { \ + struct ent data; \ + STAILQ_ENTRY(ent##_entry) entries; \ +}; \ + \ +struct ent##_test_data { \ + void (*clone_func)(struct ent *, struct ent const *); \ + void (*free_func)(struct ent *); \ + \ + STAILQ_HEAD(ent_head, ent##_entry) snapshot_data; \ +}; \ + \ +void __##ent##_test_data_init(struct ent##_test_data *, \ + void (*)(struct ent *, struct ent const *), \ + void (*freef)(struct ent *)); \ +void __##ent##_test_data_destroy(struct ent##_test_data *); \ + \ +void __##ent##_test_data_append(struct ent##_test_data *, struct ent *data);\ +int __##ent##_test_data_foreach(struct ent##_test_data *, \ + int (*)(struct ent *, void *), void *); \ +int __##ent##_test_data_compare(struct ent##_test_data *, \ + struct ent##_test_data *, int (*)(struct ent *, struct ent *, \ + void *), void *); \ +struct ent *__##ent##_test_data_find(struct ent##_test_data *, struct ent *,\ + int (*)(struct ent *, struct ent *, void *), void *); \ +void __##ent##_test_data_clear(struct ent##_test_data *); + +#define TEST_DATA_INIT(ent, td, clonef, freef)\ + __##ent##_test_data_init(td, clonef, freef) +#define TEST_DATA_DESTROY(ent, td) __##ent##_test_data_destroy(td) +#define TEST_DATA_APPEND(ent, td, d) __##ent##_test_data_append(td, d) +#define TEST_DATA_FOREACH(ent, td, f, mdata)\ + __##ent##_test_data_foreach(td, f, mdata) +#define TEST_DATA_COMPARE(ent, td1, td2, fcmp, mdata)\ + __##ent##_test_data_compare(td1, td2, fcmp, mdata); +#define TEST_DATA_FIND(ent, td, d, fcmp, mdata)\ + __##ent##_test_data_find(td, d, fcmp, mdata) +#define TEST_DATA_CLEAR(ent, td) __##ent##_test_data_clear(td) + +#define IMPLEMENT_TEST_DATA(ent) \ +void \ +__##ent##_test_data_init(struct ent##_test_data *td, \ + void (*clonef)(struct ent *, struct ent const *), \ + void (*freef)(struct ent *)) \ +{ \ + ATF_REQUIRE(td != NULL); \ + ATF_REQUIRE(clonef != NULL); \ + ATF_REQUIRE(freef != NULL); \ + \ + memset(td, 0, sizeof(*td)); \ + td->clone_func = clonef; \ + td->free_func = freef; \ + STAILQ_INIT(&td->snapshot_data); \ +} \ + \ +void \ +__##ent##_test_data_destroy(struct ent##_test_data *td) \ +{ \ + __##ent##_test_data_clear(td); \ +} \ + \ +void \ +__##ent##_test_data_append(struct ent##_test_data *td, struct ent *app_data)\ +{ \ + struct ent##_entry *e; \ + \ + ATF_REQUIRE(td != NULL); \ + ATF_REQUIRE(app_data != NULL); \ + \ + e = (struct ent##_entry *)malloc(sizeof(struct ent##_entry)); \ + ATF_REQUIRE(e != NULL); \ + memset(e, 0, sizeof(struct ent##_entry)); \ + \ + td->clone_func(&e->data, app_data); \ + STAILQ_INSERT_TAIL(&td->snapshot_data, e, entries); \ +} \ + \ +int \ +__##ent##_test_data_foreach(struct ent##_test_data *td, \ + int (*forf)(struct ent *, void *), void *mdata) \ +{ \ + struct ent##_entry *e; \ + int rv; \ + \ + ATF_REQUIRE(td != NULL); \ + ATF_REQUIRE(forf != NULL); \ + \ + rv = 0; \ + STAILQ_FOREACH(e, &td->snapshot_data, entries) { \ + rv = forf(&e->data, mdata); \ + if (rv != 0) \ + break; \ + } \ + \ + return (rv); \ +} \ + \ +int \ +__##ent##_test_data_compare(struct ent##_test_data *td1, struct ent##_test_data *td2,\ + int (*cmp_func)(struct ent *, struct ent *, void *), void *mdata)\ +{ \ + struct ent##_entry *e1, *e2; \ + int rv; \ + \ + ATF_REQUIRE(td1 != NULL); \ + ATF_REQUIRE(td2 != NULL); \ + ATF_REQUIRE(cmp_func != NULL); \ + \ + e1 = STAILQ_FIRST(&td1->snapshot_data); \ + e2 = STAILQ_FIRST(&td2->snapshot_data); \ + \ + rv = 0; \ + do { \ + if ((e1 == NULL) || (e2 == NULL)) { \ + if (e1 == e2) \ + return (0); \ + else \ + return (-1); \ + } \ + \ + rv = cmp_func(&e1->data, &e2->data, mdata); \ + e1 = STAILQ_NEXT(e1, entries); \ + e2 = STAILQ_NEXT(e2, entries); \ + } while (rv == 0); \ + \ + return (rv); \ +} \ + \ +struct ent * \ +__##ent##_test_data_find(struct ent##_test_data *td, struct ent *data, \ + int (*cmp)(struct ent *, struct ent *, void *), void *mdata) \ +{ \ + struct ent##_entry *e; \ + struct ent *result; \ + \ + ATF_REQUIRE(td != NULL); \ + ATF_REQUIRE(cmp != NULL); \ + \ + result = NULL; \ + STAILQ_FOREACH(e, &td->snapshot_data, entries) { \ + if (cmp(&e->data, data, mdata) == 0) { \ + result = &e->data; \ + break; \ + } \ + } \ + \ + return (result); \ +} \ + \ + \ +void \ +__##ent##_test_data_clear(struct ent##_test_data *td) \ +{ \ + struct ent##_entry *e; \ + ATF_REQUIRE(td != NULL); \ + \ + while (!STAILQ_EMPTY(&td->snapshot_data)) { \ + e = STAILQ_FIRST(&td->snapshot_data); \ + STAILQ_REMOVE_HEAD(&td->snapshot_data, entries); \ + \ + td->free_func(&e->data); \ + free(e); \ + e = NULL; \ + } \ +} + +#define DECLARE_TEST_FILE_SNAPSHOT(ent) \ +struct ent##_snp_param { \ + FILE *fp; \ + void (*sdump_func)(struct ent *, char *, size_t); \ +}; \ + \ +int __##ent##_snapshot_write_func(struct ent *, void *); \ +int __##ent##_snapshot_write(char const *, struct ent##_test_data *, \ + void (*)(struct ent *, char *, size_t)); \ +int __##ent##_snapshot_read(char const *, struct ent##_test_data *, \ + int (*)(struct ent *, char *)); + +#define TEST_SNAPSHOT_FILE_WRITE(ent, fname, td, f) \ + __##ent##_snapshot_write(fname, td, f) +#define TEST_SNAPSHOT_FILE_READ(ent, fname, td, f) \ + __##ent##_snapshot_read(fname, td, f) + +#define IMPLEMENT_TEST_FILE_SNAPSHOT(ent) \ +int \ +__##ent##_snapshot_write_func(struct ent *data, void *mdata) \ +{ \ + char buffer[1024]; \ + struct ent##_snp_param *param; \ + \ + ATF_REQUIRE(data != NULL); \ + \ + param = (struct ent##_snp_param *)mdata; \ + param->sdump_func(data, buffer, sizeof(buffer)); \ + fputs(buffer, param->fp); \ + fputc('\n', param->fp); \ + \ + return (0); \ +} \ + \ +int \ +__##ent##_snapshot_write(char const *fname, struct ent##_test_data *td, \ + void (*sdump_func)(struct ent *, char *, size_t)) \ +{ \ + struct ent##_snp_param param; \ + \ + ATF_REQUIRE(fname != NULL); \ + ATF_REQUIRE(td != NULL); \ + \ + param.fp = fopen(fname, "w"); \ + if (param.fp == NULL) \ + return (-1); \ + \ + param.sdump_func = sdump_func; \ + __##ent##_test_data_foreach(td, __##ent##_snapshot_write_func, ¶m);\ + fclose(param.fp); \ + \ + return (0); \ +} \ + \ +int \ +__##ent##_snapshot_read(char const *fname, struct ent##_test_data *td, \ + int (*read_func)(struct ent *, char *)) \ +{ \ + char buffer[1024]; \ + struct ent data; \ + char *s; \ + FILE *fi; \ + size_t len; \ + int rv; \ + \ + ATF_REQUIRE(fname != NULL); \ + ATF_REQUIRE(td != NULL); \ + \ + fi = fopen(fname, "r"); \ + if (fi == NULL) \ + return (-1); \ + \ + rv = 0; \ + memset(buffer, 0, sizeof(buffer)); \ + while (!feof(fi)) { \ + s = fgets(buffer, sizeof(buffer), fi); \ + if (s != NULL && s[0] != '#') { \ + len = strlen(s); \ + if (len == 0) \ + continue; \ + if (buffer[len - 1] == '\n') \ + buffer[len -1] = '\0'; \ + \ + rv = read_func(&data, s); \ + if (rv == 0) { \ + __##ent##_test_data_append(td, &data); \ + td->free_func(&data); \ + } else \ + goto fin; \ + } \ + } \ + \ +fin: \ + fclose(fi); \ + return (rv); \ +} + +#define DECLARE_1PASS_TEST(ent) \ +int __##ent##_1pass_test(struct ent##_test_data *, \ + int (*)(struct ent *, void *), \ + void *); + +#define DO_1PASS_TEST(ent, td, f, mdata) \ + __##ent##_1pass_test(td, f, mdata) + +#define IMPLEMENT_1PASS_TEST(ent) \ +int \ +__##ent##_1pass_test(struct ent##_test_data *td, \ + int (*tf)(struct ent *, void *), \ + void *mdata) \ +{ \ + int rv; \ + rv = __##ent##_test_data_foreach(td, tf, mdata); \ + \ + return (rv); \ +} + +#define DECLARE_2PASS_TEST(ent) \ +int __##ent##_2pass_test(struct ent##_test_data *, \ + struct ent##_test_data *, \ + int (*)(struct ent *, struct ent *, void *), void *); + +#define DO_2PASS_TEST(ent, td1, td2, f, mdata) \ + __##ent##_2pass_test(td1, td2, f, mdata) + +#define IMPLEMENT_2PASS_TEST(ent) \ +int \ +__##ent##_2pass_test(struct ent##_test_data *td1, \ + struct ent##_test_data *td2, \ + int (*cmp_func)(struct ent *, struct ent *, void *), \ + void *cmp_mdata) \ +{ \ + int rv; \ + \ + rv = __##ent##_test_data_compare(td1, td2, cmp_func, cmp_mdata); \ + return (rv); \ +} Property changes on: user/ngie/stable-10-libnv/lib/libc/tests/nss/testutil.h ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: user/ngie/stable-10-libnv/lib/libc/tests/resolv/Makefile =================================================================== --- user/ngie/stable-10-libnv/lib/libc/tests/resolv/Makefile (nonexistent) +++ user/ngie/stable-10-libnv/lib/libc/tests/resolv/Makefile (revision 292857) @@ -0,0 +1,15 @@ +# $FreeBSD$ + +TESTSDIR= ${TESTSBASE}/lib/libc/resolv +BINDIR= ${TESTSDIR} + +FILES+= mach + +ATF_TESTS_C+= resolv_test + +# Note: this test relies on being dynamically linked. You will get a +# spurious PASS for a statically linked test. +DPADD.resolv_test+= ${LIBPTHREAD} +LDADD.resolv_test+= -lpthread + +.include Property changes on: user/ngie/stable-10-libnv/lib/libc/tests/resolv/Makefile ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: user/ngie/stable-10-libnv/lib/libc/tests/resolv/resolv_test.c =================================================================== --- user/ngie/stable-10-libnv/lib/libc/tests/resolv/resolv_test.c (nonexistent) +++ user/ngie/stable-10-libnv/lib/libc/tests/resolv/resolv_test.c (revision 292857) @@ -0,0 +1,331 @@ +/* $NetBSD: resolv.c,v 1.6 2004/05/23 16:59:11 christos Exp $ */ + +/*- + * Copyright (c) 2004 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +/* $FreeBSD$ */ +#include +__RCSID("$NetBSD: resolv.c,v 1.6 2004/05/23 16:59:11 christos Exp $"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define NTHREADS 10 +#define NHOSTS 100 +#define WS " \t\n\r" + +enum method { + METHOD_GETADDRINFO, + METHOD_GETHOSTBY, + METHOD_GETIPNODEBY +}; + +static StringList *hosts = NULL; +static enum method method = METHOD_GETADDRINFO; +static int *ask = NULL; +static int *got = NULL; + +static void load(const char *); +static void resolvone(int); +static void *resolvloop(void *); +static void run(int *); + +static pthread_mutex_t stats = PTHREAD_MUTEX_INITIALIZER; + +static void +load(const char *fname) +{ + FILE *fp; + size_t len; + char *line; + + if ((fp = fopen(fname, "r")) == NULL) + ATF_REQUIRE(fp != NULL); + while ((line = fgetln(fp, &len)) != NULL) { + char c = line[len]; + char *ptr; + line[len] = '\0'; + for (ptr = strtok(line, WS); ptr; ptr = strtok(NULL, WS)) { + if (ptr == '\0' || ptr[0] == '#') + continue; + sl_add(hosts, strdup(ptr)); + } + line[len] = c; + } + + (void)fclose(fp); +} + +static int +resolv_getaddrinfo(pthread_t self, char *host, int port) +{ + char portstr[6], buf[1024], hbuf[NI_MAXHOST], pbuf[NI_MAXSERV]; + struct addrinfo hints, *res; + int error, len; + + snprintf(portstr, sizeof(portstr), "%d", port); + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_flags = AI_PASSIVE; + hints.ai_socktype = SOCK_STREAM; + error = getaddrinfo(host, portstr, &hints, &res); + len = snprintf(buf, sizeof(buf), "%p: host %s %s\n", + self, host, error ? "not found" : "ok"); + (void)write(STDOUT_FILENO, buf, len); + if (error == 0) { + memset(hbuf, 0, sizeof(hbuf)); + memset(pbuf, 0, sizeof(pbuf)); + getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf), + pbuf, sizeof(pbuf), 0); + len = snprintf(buf, sizeof(buf), + "%p: reverse %s %s\n", self, hbuf, pbuf); + (void)write(STDOUT_FILENO, buf, len); + } + if (error == 0) + freeaddrinfo(res); + return error; +} + +static int +resolv_gethostby(pthread_t self, char *host) +{ + char buf[1024]; + struct hostent *hp, *hp2; + int len; + + hp = gethostbyname(host); + len = snprintf(buf, sizeof(buf), "%p: host %s %s\n", + self, host, (hp == NULL) ? "not found" : "ok"); + (void)write(STDOUT_FILENO, buf, len); + if (hp) { + memcpy(buf, hp->h_addr, hp->h_length); + hp2 = gethostbyaddr(buf, hp->h_length, hp->h_addrtype); + if (hp2) { + len = snprintf(buf, sizeof(buf), + "%p: reverse %s\n", self, hp2->h_name); + (void)write(STDOUT_FILENO, buf, len); + } + } + return hp ? 0 : -1; +} + +static int +resolv_getipnodeby(pthread_t self, char *host) +{ + char buf[1024]; + struct hostent *hp, *hp2; + int len, h_error; + + hp = getipnodebyname(host, AF_INET, 0, &h_error); + len = snprintf(buf, sizeof(buf), "%p: host %s %s\n", + self, host, (hp == NULL) ? "not found" : "ok"); + (void)write(STDOUT_FILENO, buf, len); + if (hp) { + memcpy(buf, hp->h_addr, hp->h_length); + hp2 = getipnodebyaddr(buf, hp->h_length, hp->h_addrtype, + &h_error); + if (hp2) { + len = snprintf(buf, sizeof(buf), + "%p: reverse %s\n", self, hp2->h_name); + (void)write(STDOUT_FILENO, buf, len); + } + if (hp2) + freehostent(hp2); + } + if (hp) + freehostent(hp); + return hp ? 0 : -1; +} + +static void +resolvone(int n) +{ + char buf[1024]; + pthread_t self = pthread_self(); + size_t i = (random() & 0x0fffffff) % hosts->sl_cur; + char *host = hosts->sl_str[i]; + struct addrinfo hints, *res; + int error, len; + + len = snprintf(buf, sizeof(buf), "%p: %d resolving %s %d\n", + self, n, host, (int)i); + (void)write(STDOUT_FILENO, buf, len); + switch (method) { + case METHOD_GETADDRINFO: + error = resolv_getaddrinfo(self, host, i); + break; + case METHOD_GETHOSTBY: + error = resolv_gethostby(self, host); + break; + case METHOD_GETIPNODEBY: + error = resolv_getipnodeby(self, host); + break; + default: + break; + } + pthread_mutex_lock(&stats); + ask[i]++; + got[i] += error == 0; + pthread_mutex_unlock(&stats); +} + +static void * +resolvloop(void *p) +{ + int *nhosts = (int *)p; + if (*nhosts == 0) + return NULL; + do + resolvone(*nhosts); + while (--(*nhosts)); + return NULL; +} + +static void +run(int *nhosts) +{ + pthread_t self; + int rc; + + self = pthread_self(); + rc = pthread_create(&self, NULL, resolvloop, nhosts); + ATF_REQUIRE_MSG(rc == 0, "pthread_create failed: %s", strerror(rc)); +} + +static int +run_tests(const char *hostlist_file, enum method method) +{ + int nthreads = NTHREADS; + int nhosts = NHOSTS; + int i, c, done, *nleft; + hosts = sl_init(); + + srandom(1234); + + load(hostlist_file); + + ATF_REQUIRE_MSG(0 < hosts->sl_cur, "0 hosts in %s", hostlist_file); + + nleft = malloc(nthreads * sizeof(int)); + ATF_REQUIRE(nleft != NULL); + + ask = calloc(hosts->sl_cur, sizeof(int)); + ATF_REQUIRE(ask != NULL); + + got = calloc(hosts->sl_cur, sizeof(int)); + ATF_REQUIRE(got != NULL); + + for (i = 0; i < nthreads; i++) { + nleft[i] = nhosts; + run(&nleft[i]); + } + + for (done = 0; !done;) { + done = 1; + for (i = 0; i < nthreads; i++) { + if (nleft[i] != 0) { + done = 0; + break; + } + } + sleep(1); + } + c = 0; + for (i = 0; i < hosts->sl_cur; i++) { + if (ask[i] != got[i] && got[i] != 0) { + printf("Error: host %s ask %d got %d\n", + hosts->sl_str[i], ask[i], got[i]); + c++; + } + } + free(nleft); + free(ask); + free(got); + sl_free(hosts, 1); + return c; +} + +#define HOSTLIST_FILE "mach" + +#define RUN_TESTS(tc, method) \ +do { \ + char *_hostlist_file; \ + ATF_REQUIRE(0 < asprintf(&_hostlist_file, "%s/%s", \ + atf_tc_get_config_var(tc, "srcdir"), HOSTLIST_FILE)); \ + ATF_REQUIRE(run_tests(_hostlist_file, method) == 0); \ +} while(0) + +ATF_TC(getaddrinfo_test); +ATF_TC_HEAD(getaddrinfo_test, tc) { + atf_tc_set_md_var(tc, "timeout", "450"); +} +ATF_TC_BODY(getaddrinfo_test, tc) +{ + + RUN_TESTS(tc, METHOD_GETADDRINFO); +} + +ATF_TC(gethostby_test); +ATF_TC_HEAD(gethostby_test, tc) { + atf_tc_set_md_var(tc, "timeout", "450"); +} +ATF_TC_BODY(gethostby_test, tc) +{ + + RUN_TESTS(tc, METHOD_GETHOSTBY); +} + +ATF_TC(getipnodeby_test); +ATF_TC_HEAD(getipnodeby_test, tc) { + + atf_tc_set_md_var(tc, "timeout", "450"); +} +ATF_TC_BODY(getipnodeby_test, tc) +{ + + RUN_TESTS(tc, METHOD_GETIPNODEBY); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, getaddrinfo_test); + ATF_TP_ADD_TC(tp, gethostby_test); + ATF_TP_ADD_TC(tp, getipnodeby_test); + + return (atf_no_error()); +} Property changes on: user/ngie/stable-10-libnv/lib/libc/tests/resolv/resolv_test.c ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: user/ngie/stable-10-libnv/lib/libc/tests/resolv/mach =================================================================== --- user/ngie/stable-10-libnv/lib/libc/tests/resolv/mach (nonexistent) +++ user/ngie/stable-10-libnv/lib/libc/tests/resolv/mach (revision 292857) @@ -0,0 +1,46 @@ +# $FreeBSD$ +localhost +anoncvs.cirr.com +anoncvs.netbsd.se +antioche.antioche.eu.org +centaurus.4web.cz +chur.math.ntnu.no +console.netbsd.org +cvs.netbsd.org +cvsup.netbsd.se +ftp.chg.ru +ftp.estpak.ee +ftp.fsn.hu +ftp.funet.fi +ftp.netbsd.org +ftp.nluug.nl +ftp.plig.org +ftp.uni-erlangen.de +ftp.xgate.co.kr +gd.tuwien.ac.at +gort.ludd.luth.se +irc.warped.net +knug.youn.co.kr +mail.jp.netbsd.org +mail.netbsd.org +melanoma.cs.rmit.edu.au +mirror.aarnet.edu.au +moon.vub.ac.be +net.bsd.cz +netbsd.3miasto.net +netbsd.4ka.mipt.ru +netbsd.csie.nctu.edu.tw +netbsd.enderunix.org +netbsd.ftp.fu-berlin.de +netbsd.pair.com +netbsdiso.interoute.net.uk +netbsdwww.cs.rmit.edu.au +netbsdwww.interoute.net.uk +ns.netbsd.org +skeleton.phys.spbu.ru +www.en.netbsd.de +www.netbsd.cl +www.netbsd.nl +www.netbsd.org +www.netbsd.ro +zeppo.rediris.es Property changes on: user/ngie/stable-10-libnv/lib/libc/tests/resolv/mach ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: user/ngie/stable-10-libnv/lib/liblzma/Makefile =================================================================== --- user/ngie/stable-10-libnv/lib/liblzma/Makefile (revision 292856) +++ user/ngie/stable-10-libnv/lib/liblzma/Makefile (revision 292857) @@ -1,173 +1,175 @@ # $FreeBSD$ LIB= lzma LZMADIR= ${.CURDIR}/../../contrib/xz/src/liblzma .PATH: ${LZMADIR}/../common SRCS+= tuklib_physmem.c tuklib_cpucores.c .PATH: ${LZMADIR}/api/lzma MAININCS= ../lzma.h MAININCSDIR= ${INCLUDEDIR} LZMAINCS+= base.h \ bcj.h \ block.h \ check.h \ container.h \ delta.h \ filter.h \ hardware.h \ index.h \ index_hash.h \ lzma12.h \ stream_flags.h \ version.h \ vli.h LZMAINCSDIR= ${INCLUDEDIR}/lzma INCSGROUPS= MAININCS LZMAINCS .PATH: ${LZMADIR}/common SRCS+= common.c \ block_util.c \ easy_preset.c \ filter_common.c \ hardware_physmem.c \ hardware_cputhreads.c \ index.c \ stream_flags_common.c \ vli_size.c \ alone_encoder.c \ block_buffer_encoder.c \ block_encoder.c \ block_header_encoder.c \ easy_buffer_encoder.c \ easy_encoder.c \ easy_encoder_memusage.c \ filter_buffer_encoder.c \ filter_encoder.c \ filter_flags_encoder.c \ index_encoder.c \ stream_buffer_encoder.c \ stream_encoder.c \ stream_flags_encoder.c \ vli_encoder.c \ alone_decoder.c \ auto_decoder.c \ block_buffer_decoder.c \ block_decoder.c \ block_header_decoder.c \ easy_decoder_memusage.c \ filter_buffer_decoder.c \ filter_decoder.c \ filter_flags_decoder.c \ index_decoder.c \ index_hash.c \ stream_buffer_decoder.c \ stream_decoder.c \ stream_flags_decoder.c \ stream_encoder_mt.c \ vli_decoder.c \ outqueue.c .PATH: ${LZMADIR}/check SRCS+= check.c \ crc32_table.c \ crc64_table.c \ sha256.c .if defined(MACHINE_ARCH) && ${MACHINE_ARCH} == "i386" SRCS+= crc32_x86.S \ crc64_x86.S ACFLAGS+= -Wa,--noexecstack .else SRCS+= crc32_fast.c \ crc64_fast.c .endif .PATH: ${LZMADIR}/lz SRCS+= lz_encoder.c \ lz_encoder_mf.c \ lz_decoder.c .PATH: ${LZMADIR}/lzma SRCS+= lzma_encoder.c \ lzma_encoder_presets.c \ lzma_encoder_optimum_fast.c \ lzma_encoder_optimum_normal.c \ fastpos_table.c \ lzma_decoder.c \ lzma2_encoder.c \ lzma2_decoder.c .PATH: ${LZMADIR}/rangecoder SRCS+= price_table.c .PATH: ${LZMADIR}/delta SRCS+= delta_common.c \ delta_encoder.c \ delta_decoder.c .PATH: ${LZMADIR}/simple SRCS+= simple_coder.c \ simple_encoder.c \ simple_decoder.c \ x86.c \ powerpc.c \ ia64.c \ arm.c \ armthumb.c \ sparc.c .PATH: ${LZMADIR} VERSION_MAJOR!= awk '$$1 == "\#define" && $$2 == "LZMA_VERSION_MAJOR" {print $$3 } ' \ ${LZMADIR}/api/lzma/version.h VERSION_MINOR!= awk '$$1 == "\#define" && $$2 == "LZMA_VERSION_MINOR" {print $$3 } ' \ ${LZMADIR}/api/lzma/version.h VERSION_PATCH!= awk '$$1 == "\#define" && $$2 == "LZMA_VERSION_PATCH" {print $$3 } ' \ ${LZMADIR}/api/lzma/version.h WARNS?= 3 CFLAGS+= -DHAVE_CONFIG_H \ -DTUKLIB_SYMBOL_PREFIX=lzma_ \ -I${.CURDIR} \ -I${LZMADIR}/api \ -I${LZMADIR}/common \ -I${LZMADIR}/check \ -I${LZMADIR}/lz \ -I${LZMADIR}/rangecoder \ -I${LZMADIR}/lzma \ -I${LZMADIR}/delta \ -I${LZMADIR}/simple \ -I${LZMADIR}/../common DPADD+= ${LIBPTHREAD} LDADD+= -lpthread VERSION_DEF= ${.CURDIR}/Versions.def SYMBOL_MAPS= ${.CURDIR}/Symbol.map CFLAGS+= -DSYMBOL_VERSIONING CLEANFILES+= liblzma.pc +.if !defined(LIBRARIES_ONLY) all: liblzma.pc liblzma.pc: liblzma.pc.in @sed -e 's,@prefix@,/usr,g ; \ s,@exec_prefix@,/usr,g ; \ - s,@libdir@,${LIBDIR},g ; \ - s,@includedir@,${INCLUDEDIR},g ; \ + s,@libdir@,/usr/lib,g ; \ + s,@includedir@,/usr/include,g ; \ s,@PACKAGE_URL@,http://tukaani.org/xz/,g ; \ s,@PACKAGE_VERSION@,${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH},g ; \ s,@PTHREAD_CFLAGS@,,g ; \ s,@PTHREAD_LIBS@,,g' ${.ALLSRC} > ${.TARGET} beforeinstall: @${INSTALL} -C -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} \ liblzma.pc ${DESTDIR}${LIBDATADIR}/pkgconfig +.endif .include Index: user/ngie/stable-10-libnv/share/examples/tests/tests/atf/printf_test.c =================================================================== --- user/ngie/stable-10-libnv/share/examples/tests/tests/atf/printf_test.c (revision 292856) +++ user/ngie/stable-10-libnv/share/examples/tests/tests/atf/printf_test.c (revision 292857) @@ -1,155 +1,157 @@ /* $FreeBSD$ * * Copyright 2013 Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Google Inc. nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * INTRODUCTION * * This sample test program implements various test cases for the printf(3) * family of functions in order to demonstrate the usage of the ATF C API * (see atf-c-api(3)). * * Note that this test program is called printf_test because it is intended * to validate various functions of the printf(3) family. For this reason, * each test is prefixed with the name of the function under test followed * by a description of the specific condition being validated. You should * use a similar naming scheme for your own tests. */ #include #include #include /* * This is the simplest form of a test case definition: a test case * without a header. * * In most cases, this is the definition you will want to use. However, * make absolutely sure that the test case name is descriptive enough. * Multi-word test case names are encouraged. Keep in mind that these * are exposed to the reader in the test reports, and the goal is for * the combination of the test program plus the name of the test case to * give a pretty clear idea of what specific condition the test is * validating. */ ATF_TC_WITHOUT_HEAD(snprintf__two_formatters); ATF_TC_BODY(snprintf__two_formatters, tc) { char buffer[128]; /* This first require-style check invokes the function we are * interested in testing. This will cause the test to fail if * the condition provided to ATF_REQUIRE is not met. */ ATF_REQUIRE(snprintf(buffer, sizeof(buffer), "%s, %s!", "Hello", "tests") > 0); /* This second check-style check compares that the result of the * snprintf call we performed above is correct. We use a check * instead of a require. */ ATF_CHECK_STREQ("Hello, tests!", buffer); } /* * This is a more complex form of a test case definition: a test case * with a header and a body. You should always favor the simpler * definition above unless you have to override specific metadata * variables. * * See atf-test-case(4) and kyua-atf-interface(1) for details on all * available properties. */ ATF_TC(snprintf__overflow); ATF_TC_HEAD(snprintf__overflow, tc) { /* In this specific case, we define a textual description for * the test case, which is later exported to the reports for * documentation purposes. * * However, note again that you should favor highly descriptive * test case names to textual descriptions. */ atf_tc_set_md_var(tc, "descr", "This test case validates the proper " "truncation of the output string from snprintf when it does not " "fit the provided buffer."); } ATF_TC_BODY(snprintf__overflow, tc) { char buffer[10]; /* This is a similar test to the above, but in this case we do the * test ourselves and forego the ATF_* macros. Note that we use the * atf_tc_fail() function instead of exit(2) or similar because we * want Kyua to have access to the failure message. * * In general, prefer using the ATF_* macros wherever possible. Only * resort to manual tests when the macros are unsuitable (and consider * filing a feature request to get a new macro if you think your case * is generic enough). */ if (snprintf(buffer, sizeof(buffer), "0123456789abcdef") != 16) atf_tc_fail("snprintf did not return the expected number " "of characters"); ATF_CHECK(strcmp(buffer, "012345678") == 0); } /* * Another simple test case, but this time with side-effects. This * particular test case modifies the contents of the current directory * and does not clean up after itself, which is perfectly fine. */ ATF_TC_WITHOUT_HEAD(fprintf__simple_string); ATF_TC_BODY(fprintf__simple_string, tc) { const char *contents = "This is a message\n"; FILE *output = fopen("test.txt", "w"); ATF_REQUIRE(fprintf(output, "%s", contents) > 0); fclose(output); /* The ATF C library provides more than just macros to verify the * outcome of expressions. It also includes various helper functions * to work with files and processes. Here is just a simple * example. */ ATF_REQUIRE(atf_utils_compare_file("test.txt", contents)); /* Of special note here is that we are NOT deleting the * temporary files we created in this test. Kyua takes care of * this cleanup automatically and tests can (and should) rely on * this behavior. */ } /* * Lastly, we tell ATF which test cases exist in this program. This * function should not do anything other than this registration. */ ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, snprintf__two_formatters); ATF_TP_ADD_TC(tp, snprintf__overflow); ATF_TP_ADD_TC(tp, fprintf__simple_string); + + return (atf_no_error()); } Index: user/ngie/stable-10-libnv/share/mk/bsd.README =================================================================== --- user/ngie/stable-10-libnv/share/mk/bsd.README (revision 292856) +++ user/ngie/stable-10-libnv/share/mk/bsd.README (revision 292857) @@ -1,490 +1,494 @@ # @(#)bsd.README 8.2 (Berkeley) 4/2/94 # $FreeBSD$ This is the README file for the "include" files for the FreeBSD source tree. The files are installed in /usr/share/mk, and are by convention, named with the suffix ".mk". These files store several build options and should be handled with caution. Note, this file is not intended to replace reading through the .mk files for anything tricky. There are two main types of make include files. One type is the generally usable make include files, such as bsd.prog.mk and bsd.lib.mk. The other is the internal make include files, such as bsd.files.mk and bsd.man.mk, which can not/should not be used directly but are used by the other make include files. In most cases it is only interesting to include bsd.prog.mk or bsd.lib.mk. bsd.cpu.mk - sets CPU/arch-related variables bsd.crunchgen.mk - building crunched binaries using crunchgen(1) bsd.dep.mk - handle Makefile dependencies bsd.doc.mk - building troff system documents bsd.files.mk - install of general purpose files bsd.incs.mk - install of include files bsd.info.mk - building GNU Info hypertext system bsd.init.mk - initialization for the make include files bsd.kmod.mk - building loadable kernel modules bsd.lib.mk - support for building libraries bsd.libnames.mk - define library names bsd.links.mk - install of links (sym/hard) bsd.man.mk - install of manual pages and their links bsd.nls.mk - build and install of NLS catalogs bsd.obj.mk - creating 'obj' directories and cleaning up bsd.own.mk - define common variables bsd.port.mk - building ports bsd.port.post.mk - building ports bsd.port.pre.mk - building ports bsd.port.subdir.mk - targets for building subdirectories for ports bsd.prog.mk - building programs from source files bsd.snmpmod.mk - building modules for the SNMP daemon bsnmpd bsd.subdir.mk - targets for building subdirectories bsd.sys.mk - common settings used for building FreeBSD sources bsd.test.mk - building test programs from source files sys.mk - default rules for all makes This file does not document bsd.port*.mk. They are documented in ports(7). See also make(1), mkdep(1), style.Makefile(5) and `PMake - A Tutorial', located in /usr/share/doc/psd/12.make. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Random things worth knowing about this document: If appropriate when documenting the variables the default value is indicated using square brackets e.g. [gzip]. In some cases the default value depend on other values (e.g. system architecture). In these cases the most common value is indicated. This document contains some simple examples of the usage of the BSD make include files. For more examples look at the makefiles in the FreeBSD source tree. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= RANDOM THINGS WORTH KNOWING: The files are like C-style #include files, and pretty much behave like you'd expect. The syntax is slightly different in that a single '.' is used instead of the hash mark, i.e. ".include ". One difference that will save you lots of debugging time is that inclusion of the file is normally done at the *end* of the Makefile. The reason for this is because .mk files often modify variables and behavior based on the values of variables set in the Makefile. To make this work, remember that the FIRST target found is the target that is used, i.e. if the Makefile has: a: echo a a: echo a number two the command "make a" will echo "a". To make things confusing, the SECOND variable assignment is the overriding one, i.e. if the Makefile has: a= foo a= bar b: echo ${a} the command "make b" will echo "bar". This is for compatibility with the way the V7 make behaved. It's fairly difficult to make the BSD .mk files work when you're building multiple programs in a single directory. It's a lot easier to split up the programs than to deal with the problem. Most of the agony comes from making the "obj" directory stuff work right, not because we switch to a new version of make. So, don't get mad at us, figure out a better way to handle multiple architectures so we can quit using the symbolic link stuff. (Imake doesn't count.) The file .depend in the source directory is expected to contain dependencies for the source files. This file is read automatically by make after reading the Makefile. The variable DESTDIR works as before. It's not set anywhere but will change the tree where the file gets installed. The profiled libraries are no longer built in a different directory than the regular libraries. A new suffix, ".po", is used to denote a profiled object. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= The include file has the default rules for all makes, in the BSD environment or otherwise. You probably don't want to touch this file. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= The include file handles installing manual pages and their links. It has three targets: all-man: build manual pages. maninstall: install the manual pages and their links. manlint: verify the validity of manual pages. It sets/uses the following variables: MANDIR Base path for manual installation. MANGRP Manual group. MANOWN Manual owner. MANMODE Manual mode. MANSUBDIR Subdirectory under the manual page section, i.e. "/vax" or "/tahoe" for machine specific manual pages. MAN The manual pages to be installed (use a .1 - .9 suffix). MLINKS List of manual page links (using a .1 - .9 suffix). The linked-to file must come first, the linked file second, and there may be multiple pairs. The files are soft-linked. The include file includes a file named "../Makefile.inc" if it exists. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= The include file contains the owners, groups, etc. for both manual pages and binaries. It has no targets. It sets/uses the following variables: BINGRP Binary group. BINOWN Binary owner. BINMODE Binary mode. MANDIR Base path for manual installation. MANGRP Manual group. MANOWN Manual owner. MANMODE Manual mode. This file is generally useful when building your own Makefiles so that they use the same default owners etc. as the rest of the tree. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= The include file handles building programs from one or more source files, along with their manual pages. It has a limited number of suffixes, consistent with the current needs of the BSD tree. It has seven targets: all: build the program and its manual page clean: remove the program and any object files. cleandir: remove all of the files removed by the target clean, as well as .depend, tags, and any manual pages. depend: make the dependencies for the source files, and store them in the file .depend. install: install the program and its manual pages; if the Makefile does not itself define the target install, the targets beforeinstall and afterinstall may also be used to cause actions immediately before and after the install target is executed. lint: run lint on the source files tags: create a tags file for the source files. It sets/uses the following variables: BINGRP Binary group. BINOWN Binary owner. BINMODE Binary mode. CLEANFILES Additional files to remove and CLEANDIRS additional directories to remove during clean and cleandir targets. "rm -f" and "rm -rf" used respectively. CFLAGS Flags to the compiler when creating C objects. FILES A list of non-executable files. The installation is controlled by the FILESNAME, FILESOWN, FILESGRP, FILESMODE, FILESDIR variables that can be further specialized by FILES_. LDADD Additional loader objects. Usually used for libraries. For example, to load with the compatibility and utility libraries, use: LDADD=-lutil -lcompat LDFLAGS Additional loader flags. LINKS The list of binary links; should be full pathnames, the linked-to file coming first, followed by the linked file. The files are hard-linked. For example, to link /bin/test and /bin/[, use: LINKS= ${DESTDIR}/bin/test ${DESTDIR}/bin/[ MAN Manual pages (should end in .1 - .9). If no MAN variable is defined, "MAN=${PROG}.1" is assumed. PROG The name of the program to build. If not supplied, nothing is built. PROG_CXX If defined, the name of the program to build. Also causes to link the program with the standard C++ library. PROG_CXX overrides the value of PROG if PROG is also set. PROGS When used with , allow building multiple PROGS_CXX PROG and PROGS_CXX in one Makefile. To define individual variables for each program the VAR.prog syntax should be used. For example: PROGS= foo bar SRCS.foo= foo_src.c LDADD.foo= -lutil SRCS.bar= bar_src.c The supported variables are BINDIR BINGRP BINMODE BINOWN CFLAGS CPPFLAGS CXXFLAGS DPADD DPLIBS DPSRCS LDADD LDFLAGS MAN MLINKS PROGNAME SRCS. PROGNAME The name that the above program will be installed as, if different from ${PROG}. SRCS List of source files to build the program. If SRCS is not defined, it's assumed to be ${PROG}.c or, if PROG_CXX is defined, ${PROG_CXX}.cc. DPADD Additional dependencies for the program. Usually used for libraries. For example, to depend on the compatibility and utility libraries use: DPADD=${LIBCOMPAT} ${LIBUTIL} There is a predefined identifier for each (non-profiled, non-shared) library and object. Library file names are transformed to identifiers by removing the extension and converting to upper case. There are no special identifiers for profiled or shared libraries or objects. The identifiers for the standard libraries are used in DPADD. This works correctly iff all the libraries are built at the same time. Unfortunately, it causes unnecessary relinks to shared libraries when only the static libraries have changed. Dependencies on shared libraries should be only on the library version numbers. STRIP The flag passed to the install program to cause the binary to be stripped. This is to be used when building your own install script so that the entire system can be made stripped/not-stripped using a single nob. SUBDIR A list of subdirectories that should be built as well. Each of the targets will execute the same target in the subdirectories. SCRIPTS A list of interpreter scripts [file.{sh,csh,pl,awk,...}]. The installation is controlled by the SCRIPTSNAME, SCRIPTSOWN, SCRIPTSGRP, SCRIPTSMODE, SCRIPTSDIR variables that can be further specialized by SCRIPTS_