|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1989 The Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * This code is derived from software contributed to Berkeley by ! 6: * Rick Macklem at The University of Guelph. ! 7: * ! 8: * Redistribution and use in source and binary forms are permitted provided ! 9: * that: (1) source distributions retain this entire copyright notice and ! 10: * comment, and (2) distributions including binaries display the following ! 11: * acknowledgement: ``This product includes software developed by the ! 12: * University of California, Berkeley and its contributors'' in the ! 13: * documentation or other materials provided with the distribution and in ! 14: * all advertising materials mentioning features or use of this software. ! 15: * Neither the name of the University nor the names of its contributors may ! 16: * be used to endorse or promote products derived from this software without ! 17: * specific prior written permission. ! 18: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED ! 19: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF ! 20: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 21: */ ! 22: ! 23: #ifndef lint ! 24: char copyright[] = ! 25: "@(#) Copyright (c) 1989 Regents of the University of California.\n\ ! 26: All rights reserved.\n"; ! 27: #endif not lint ! 28: ! 29: #ifndef lint ! 30: static char sccsid[] = "@(#)nfsd.c 5.8 (Berkeley) 6/29/90"; ! 31: #endif not lint ! 32: ! 33: #include <sys/types.h> ! 34: #include <sys/signal.h> ! 35: #include <sys/ioctl.h> ! 36: #include <sys/stat.h> ! 37: #include <sys/wait.h> ! 38: #include <sys/mount.h> ! 39: #include <sys/socket.h> ! 40: #include <sys/socketvar.h> ! 41: #include <stdio.h> ! 42: #include <syslog.h> ! 43: #include <fcntl.h> ! 44: #include <string.h> ! 45: #include <netdb.h> ! 46: #include <rpc/rpc.h> ! 47: #include <rpc/pmap_clnt.h> ! 48: #include <rpc/pmap_prot.h> ! 49: #include <nfs/rpcv2.h> ! 50: #include <nfs/nfsv2.h> ! 51: ! 52: /* Global defs */ ! 53: #ifdef DEBUG ! 54: #define syslog(e, s) fprintf(stderr,(s)) ! 55: int debug = 1; ! 56: #else ! 57: int debug = 0; ! 58: #endif ! 59: struct hadr { ! 60: u_long ha_sad; ! 61: struct hadr *ha_next; ! 62: }; ! 63: struct hadr hphead; ! 64: ! 65: /* ! 66: * Nfs server daemon mostly just a user context for nfssvc() ! 67: * 1 - do file descriptor and signal cleanup ! 68: * 2 - create server socket ! 69: * 3 - register socket with portmap ! 70: * For SOCK_DGRAM, just fork children and send them into the kernel ! 71: * by calling nfssvc() ! 72: * For connection based sockets, loop doing accepts. When you get a new socket ! 73: * from accept, fork a child that drops into the kernel via. nfssvc. ! 74: * This child will return from nfssvc when the connection is closed, so ! 75: * just shutdown() and exit(). ! 76: * The arguments are: ! 77: * -t - support tcp nfs clients ! 78: * -u - support udp nfs clients ! 79: */ ! 80: main(argc, argv) ! 81: int argc; ! 82: char **argv; ! 83: { ! 84: register int i; ! 85: register char *cp, *cp2; ! 86: register struct hadr *hp; ! 87: int udpcnt, sock, msgsock, tcpflag = 0, udpflag = 0, ret, len; ! 88: char opt; ! 89: union wait chldstat; ! 90: extern int optind; ! 91: extern char *optarg; ! 92: struct sockaddr_in saddr, msk, mtch, peername; ! 93: ! 94: while ((opt = getopt(argc, argv, "t:u:")) != EOF) ! 95: switch (opt) { ! 96: case 't': ! 97: tcpflag++; ! 98: if (cp = index(optarg, ',')) { ! 99: *cp++ = '\0'; ! 100: msk.sin_addr.s_addr = inet_addr(optarg); ! 101: if (msk.sin_addr.s_addr == -1) ! 102: usage(); ! 103: if (cp2 = index(cp, ',')) ! 104: *cp2++ = '\0'; ! 105: mtch.sin_addr.s_addr = inet_addr(cp); ! 106: if (mtch.sin_addr.s_addr == -1) ! 107: usage(); ! 108: cp = cp2; ! 109: hphead.ha_next = (struct hadr *)0; ! 110: while (cp) { ! 111: if (cp2 = index(cp, ',')) ! 112: *cp2++ = '\0'; ! 113: hp = (struct hadr *) ! 114: malloc(sizeof (struct hadr)); ! 115: hp->ha_sad = inet_addr(cp); ! 116: if (hp->ha_sad == -1) ! 117: usage(); ! 118: hp->ha_next = hphead.ha_next; ! 119: hphead.ha_next = hp; ! 120: cp = cp2; ! 121: } ! 122: } else ! 123: usage(); ! 124: break; ! 125: case 'u': ! 126: udpflag++; ! 127: if (cp = index(optarg, ',')) { ! 128: *cp++ = '\0'; ! 129: msk.sin_addr.s_addr = inet_addr(optarg); ! 130: if (msk.sin_addr.s_addr == -1) ! 131: usage(); ! 132: if (cp2 = index(cp, ',')) ! 133: *cp2++ = '\0'; ! 134: mtch.sin_addr.s_addr = inet_addr(cp); ! 135: if (mtch.sin_addr.s_addr == -1) ! 136: usage(); ! 137: if (cp2) ! 138: udpcnt = atoi(cp2); ! 139: if (udpcnt < 1 || udpcnt > 20) ! 140: udpcnt = 1; ! 141: } else ! 142: usage(); ! 143: break; ! 144: default: ! 145: case '?': ! 146: usage(); ! 147: }; ! 148: if (optind == 1) { ! 149: if (argc > 1) ! 150: udpcnt = atoi(*++argv); ! 151: if (udpcnt < 1 || udpcnt > 20) ! 152: udpcnt = 1; ! 153: msk.sin_addr.s_addr = mtch.sin_addr.s_addr = 0; ! 154: udpflag++; ! 155: } ! 156: if (debug == 0) { ! 157: daemon(0, 0); ! 158: signal(SIGINT, SIG_IGN); ! 159: signal(SIGQUIT, SIG_IGN); ! 160: signal(SIGTERM, SIG_IGN); ! 161: signal(SIGHUP, SIG_IGN); ! 162: } ! 163: openlog("nfsd:", LOG_PID, LOG_DAEMON); ! 164: pmap_unset(RPCPROG_NFS, NFS_VER2); ! 165: if (udpflag) { ! 166: if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { ! 167: syslog(LOG_ERR, "Can't create socket"); ! 168: exit(1); ! 169: } ! 170: saddr.sin_family = AF_INET; ! 171: saddr.sin_addr.s_addr = INADDR_ANY; ! 172: saddr.sin_port = htons(NFS_PORT); ! 173: if (bind(sock, &saddr, sizeof(saddr)) < 0) { ! 174: syslog(LOG_ERR, "Can't bind addr"); ! 175: exit(1); ! 176: } ! 177: if (!pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_UDP, NFS_PORT)) { ! 178: syslog(LOG_ERR, "Can't register with portmap"); ! 179: exit(1); ! 180: } ! 181: ! 182: /* ! 183: * Send the nfs datagram servers right down into the kernel ! 184: */ ! 185: for (i = 0; i < udpcnt; i++) ! 186: if (fork() == 0) { ! 187: ret = nfssvc(sock, &msk, sizeof(msk), ! 188: &mtch, sizeof(mtch)); ! 189: if (ret < 0) ! 190: syslog(LOG_ERR, "nfssvc() failed %m"); ! 191: exit(); ! 192: } ! 193: close(sock); ! 194: } ! 195: ! 196: /* ! 197: * Now set up the master STREAM server waiting for tcp connections. ! 198: */ ! 199: if (tcpflag) { ! 200: if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { ! 201: syslog(LOG_ERR, "Can't create socket"); ! 202: exit(1); ! 203: } ! 204: saddr.sin_family = AF_INET; ! 205: saddr.sin_addr.s_addr = INADDR_ANY; ! 206: saddr.sin_port = htons(NFS_PORT); ! 207: if (bind(sock, &saddr, sizeof(saddr)) < 0) { ! 208: syslog(LOG_ERR, "Can't bind addr"); ! 209: exit(1); ! 210: } ! 211: if (listen(sock, 5) < 0) { ! 212: syslog(LOG_ERR, "Listen failed"); ! 213: exit(1); ! 214: } ! 215: if (!pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_TCP, NFS_PORT)) { ! 216: syslog(LOG_ERR, "Can't register with portmap"); ! 217: exit(1); ! 218: } ! 219: /* ! 220: * Loop forever accepting connections and sending the children ! 221: * into the kernel to service the mounts. ! 222: */ ! 223: for (;;) { ! 224: if ((msgsock = accept(sock, (struct sockaddr *)0, ! 225: (int *)0)) < 0) { ! 226: syslog(LOG_ERR, "Accept failed: %m"); ! 227: exit(1); ! 228: } ! 229: /* ! 230: * Grab child termination status' just so defuncts ! 231: * are not left lying about. ! 232: */ ! 233: while (wait3(&chldstat, WNOHANG, (struct rusage *)0)) ! 234: ; ! 235: len = sizeof(peername); ! 236: if (getsockname(msgsock, &peername, &len) < 0) { ! 237: syslog(LOG_ERR, "Getsockname failed\n"); ! 238: exit(1); ! 239: } ! 240: if ((peername.sin_addr.s_addr & msk.sin_addr.s_addr) ! 241: != mtch.sin_addr.s_addr) { ! 242: hp = hphead.ha_next; ! 243: while (hp) { ! 244: if (peername.sin_addr.s_addr == ! 245: hp->ha_sad) ! 246: break; ! 247: hp = hp->ha_next; ! 248: } ! 249: if (hp == NULL) { ! 250: shutdown(msgsock, 2); ! 251: close(msgsock); ! 252: continue; ! 253: } ! 254: } ! 255: if (fork() == 0) { ! 256: close(sock); ! 257: ret = nfssvc(msgsock, &msk, sizeof(msk), ! 258: &mtch, sizeof(mtch)); ! 259: shutdown(msgsock, 2); ! 260: if (ret < 0) ! 261: syslog(LOG_NOTICE, ! 262: "Nfssvc STREAM Failed"); ! 263: exit(); ! 264: } ! 265: close(msgsock); ! 266: } ! 267: } ! 268: } ! 269: ! 270: usage() ! 271: { ! 272: fprintf(stderr, "nfsd [-t msk,mtch[,addrs]] [-u msk,mtch,numprocs]\n"); ! 273: exit(1); ! 274: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.