Annotation of ansh/src/ansh3d.c, revision 1.1
1.1 ! misho 1: /*************************************************************************
! 2: * (C) 2011 AITNET - Sofia/Bulgaria - <office@aitnet.org>
! 3: * by Michael Pounov <misho@elwix.org>
! 4: *
! 5: * $Author: misho $
! 6: * $Id: global.h,v 1.2 2011/06/08 12:45:40 misho Exp $
! 7: *
! 8: *************************************************************************/
! 9: #include "global.h"
! 10: #include "anshd.h"
! 11: #include "proc.h"
! 12:
! 13:
! 14: intptr_t Kill;
! 15: int Verbose, Crypted = 1;
! 16: proc_head_t pH;
! 17: int bpfLEN, Timeout, Daemon = 1;
! 18:
! 19: extern char compiled[], compiledby[], compilehost[];
! 20:
! 21: static void
! 22: Usage()
! 23: {
! 24: printf( " -= anshd =- ELWIX Layer3 remote management service over ICMP\n"
! 25: "=== %s === %s@%s ===\n\n"
! 26: " Syntax: ansh3d [options]\n\n"
! 27: "\t-a <host>\tBind to host address (default is *any*)\n"
! 28: "\t-i <id>\tService ID (default is 42)\n"
! 29: "\t-U <user>\tRun service with other user\n"
! 30: "\t-C <dir>\tRun service into chroot directory\n"
! 31: "\t-t <timeout>\tTimeout of login if no activity (default is 0 sec)\n"
! 32: "\t-u\t\tSwitch to unencrypted traffic between hosts\n"
! 33: "\t-b\t\tRun into batch mode (default is daemon mode)\n"
! 34: "\t-v\t\tVerbose (more -v, more verbosity ...)\n"
! 35: "\t-h\t\tThis help screen!\n"
! 36: "\n", compiled, compiledby, compilehost);
! 37: }
! 38:
! 39: static void
! 40: sig(int s)
! 41: {
! 42: int state;
! 43:
! 44: switch (s) {
! 45: case SIGHUP:
! 46: VERB(1) LOG("Got SIGHUP!\n");
! 47: break;
! 48: case SIGTERM:
! 49: Kill++;
! 50: VERB(1) LOG("Got SIGTERM!\n");
! 51: break;
! 52: case SIGPIPE:
! 53: VERB(1) LOG("Got SIGPIPE!\n");
! 54: break;
! 55: case SIGCHLD:
! 56: VERB(1) LOG("Got SIGCHLD!\n");
! 57: while (waitpid(-1, &state, WNOHANG) > 0);
! 58: break;
! 59: }
! 60: }
! 61:
! 62: static void *
! 63: hook_error(void *root, void *arg)
! 64: {
! 65: /* sched_root_task_t *r = root; */
! 66:
! 67: if (!root)
! 68: return (void*) -1;
! 69:
! 70: if (arg == (void*) EINTR)
! 71: return (void*) -1;
! 72:
! 73: return NULL;
! 74: }
! 75:
! 76: int
! 77: main(int argc, char **argv)
! 78: {
! 79: struct sockaddr sa = { 0 };
! 80: struct sockaddr_in *sin4 = (struct sockaddr_in*) &sa;
! 81: struct sockaddr_in6 *sin6 = (struct sockaddr_in6*) &sa;
! 82: struct hostent *host;
! 83: struct passwd *pass;
! 84: int fd, h = 0, uid = 0, gid = 0;
! 85: long id = ANSH_ID;
! 86: char ch, szUser[STRSIZ] = "root", szChroot[STRSIZ] = "/";
! 87: struct sigaction sact;
! 88: sched_root_task_t *root = NULL;
! 89: struct tagProc *proc;
! 90:
! 91: while ((ch = getopt(argc, argv, "hvubt:a:i:U:C:")) != -1)
! 92: switch (ch) {
! 93: case 'U':
! 94: pass = getpwnam(optarg);
! 95: if (!pass) {
! 96: printf("Error:: User %s not found!\n", optarg);
! 97: return 1;
! 98: } else {
! 99: strlcpy(szUser, optarg, sizeof szUser);
! 100: uid = pass->pw_uid;
! 101: gid = pass->pw_gid;
! 102: }
! 103: endpwent();
! 104: break;
! 105: case 'C':
! 106: if (access(optarg, R_OK)) {
! 107: printf("Error:: in chroot %s #%d - %s\n", optarg, errno, strerror(errno));
! 108: return 1;
! 109: } else
! 110: strlcpy(szChroot, optarg, sizeof szChroot);
! 111: break;
! 112: case 'i':
! 113: id = strtol(optarg, NULL, 0);
! 114: break;
! 115: case 't':
! 116: Timeout = abs(strtol(optarg, NULL, 0));
! 117: break;
! 118: case 'a':
! 119: host = gethostbyname(optarg);
! 120: if (!host) {
! 121: printf("Error:: in bind address '%s' #%d - %s\n",
! 122: optarg, h_errno, hstrerror(h_errno));
! 123: return 1;
! 124: }
! 125: switch (host->h_addrtype) {
! 126: case AF_INET:
! 127: sin4->sin_len = sizeof(struct sockaddr_in);
! 128: sin4->sin_family = AF_INET;
! 129: memcpy(&sin4->sin_addr.s_addr, host->h_addr, host->h_length);
! 130: break;
! 131: case AF_INET6:
! 132: sin6->sin6_len = sizeof(struct sockaddr_in6);
! 133: sin6->sin6_family = AF_INET6;
! 134: memcpy(&sin6->sin6_addr.s6_addr, host->h_addr, host->h_length);
! 135: break;
! 136: default:
! 137: printf("Error:: Unknown address type %d !!!\n", host->h_addrtype);
! 138: return 1;
! 139: }
! 140: break;
! 141: case 'u':
! 142: Crypted ^= Crypted;
! 143: break;
! 144: case 'b':
! 145: Daemon ^= Daemon;
! 146: break;
! 147: case 'v':
! 148: Verbose++;
! 149: break;
! 150: case 'h':
! 151: default:
! 152: Usage();
! 153: return 1;
! 154: }
! 155: argc -= optind;
! 156: argv += optind;
! 157:
! 158: /* sanity check for openned descriptor */
! 159: if (!sa.sa_family) {
! 160: sin4->sin_len = sizeof(struct sockaddr_in);
! 161: sin4->sin_family = AF_INET;
! 162: }
! 163:
! 164: /* catch signals */
! 165: memset(&sact, 0, sizeof sact);
! 166: sigemptyset(&sact.sa_mask);
! 167: sact.sa_handler = sig;
! 168: sigaction(SIGPIPE, &sact, NULL);
! 169: sigaction(SIGCHLD, &sact, NULL);
! 170: sigaction(SIGTERM, &sact, NULL);
! 171: sigaction(SIGHUP, &sact, NULL);
! 172:
! 173: openlog("ansh3d", LOG_CONS | LOG_PID, LOG_DAEMON);
! 174:
! 175: if (Daemon) {
! 176: switch (fork()) {
! 177: case -1:
! 178: ERR("Daemon mode #%d - %s\n", errno, strerror(errno));
! 179: closelog();
! 180: return 1;
! 181: case 0:
! 182: VERB(1) LOG("Welcome to dark ...\n");
! 183:
! 184: setsid();
! 185:
! 186: fd = open("/dev/null", O_WRONLY);
! 187: if (fd) {
! 188: dup2(fd, STDIN_FILENO);
! 189: dup2(fd, STDOUT_FILENO);
! 190: dup2(fd, STDERR_FILENO);
! 191: if (fd > 2)
! 192: close(fd);
! 193: }
! 194: break;
! 195: default:
! 196: VERB(1) LOG("Going to shadow land ...\n");
! 197: closelog();
! 198: return 0;
! 199: }
! 200: }
! 201:
! 202: if (ioCreatePIDFile(PIDFILE_ANSH3D, 42)) {
! 203: ERR("Error:: already started ansh3d service ...\n");
! 204: closelog();
! 205: return 1;
! 206: }
! 207:
! 208: h = PrepareL3(&sa, &bpfLEN);
! 209: if (h == -1) {
! 210: ERR("Error:: Descriptor not opened ... abort!\n");
! 211: unlink(PIDFILE_ANSH3D);
! 212: closelog();
! 213: return 2;
! 214: }
! 215:
! 216: SLIST_INIT(&pH);
! 217: if (!(proc = InitProc(h, NULL, id, bpfLEN))) {
! 218: ERR("Error:: Not enough memory ...\n");
! 219: close(h);
! 220: unlink(PIDFILE_ANSH3D);
! 221: closelog();
! 222: return 3;
! 223: }
! 224:
! 225: root = schedBegin();
! 226: if (!root) {
! 227: ERR("Scheduler not init #%d - %s\n", sched_GetErrno(), sched_GetError());
! 228: DestroyProc(id);
! 229: close(h);
! 230: unlink(PIDFILE_ANSH3D);
! 231: closelog();
! 232: return 4;
! 233: } else
! 234: root->root_hooks.hook_root.error = hook_error;
! 235:
! 236: chdir("/");
! 237: chroot(szChroot);
! 238:
! 239: setgid(gid);
! 240: setuid(uid);
! 241:
! 242: if (schedRead(root, icmpRx, (void*) id, h)) {
! 243: schedRun(root, &Kill);
! 244: } else
! 245: ERR("Failed to add reader task #%d - %s\n", sched_GetErrno(), sched_GetError());
! 246:
! 247: VERB(1) LOG("Finish process.");
! 248: schedEnd(&root);
! 249: DestroyProc(id);
! 250: close(h);
! 251: unlink(PIDFILE_ANSH3D);
! 252: closelog();
! 253: return 0;
! 254: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>