/********************************************************************** * %FUNCTION: process_option * %ARGUMENTS: * es -- event selector * name, value -- name and value of option * %RETURNS: * 0 on success; -1 on failure. * %DESCRIPTION: * Processes options. When last option has been processed, begins * command handler. ***********************************************************************/ static int process_option(EventSelector *es, char const *name, char const *value) { struct sockaddr_un addr; socklen_t len; int fd; if (!strcmp(name, "*begin*")) return 0; if (strcmp(name, "*end*")) { return l2tp_option_set(es, name, value, my_opts); } /* We have hit the end of our options. Open command socket */ if (!sockname) { sockname = "/var/run/l2tpctrl"; } (void) remove(sockname); fd = socket(AF_LOCAL, SOCK_STREAM, 0); if (fd < 0) { l2tp_set_errmsg("cmd: process_option: socket: %s", strerror(errno)); return -1; } memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_LOCAL; strncpy(addr.sun_path, sockname, sizeof(addr.sun_path) - 1); len = sizeof(addr); if (bind(fd, (struct sockaddr *) &addr, SUN_LEN(&addr)) < 0) { l2tp_set_errmsg("cmd: process_option: bind: %s", strerror(errno)); close(fd); return -1; } (void) chmod(sockname, 0600); if (listen(fd, 5) < 0) { l2tp_set_errmsg("cmd: process_option: listen: %s", strerror(errno)); close(fd); return -1; } /* Ignore sigpipe */ signal(SIGPIPE, SIG_IGN); /* Add an accept handler */ if (!EventTcp_CreateAcceptor(es, fd, cmd_acceptor)) { l2tp_set_errmsg("cmd: process_option: EventTcp_CreateAcceptor: %s", strerror(errno)); close(fd); return -1; } return 0; }
/********************************************************************** * %FUNCTION: handle_option * %ARGUMENTS: * es -- event selector * name -- name of option * value -- option's value * %RETURNS: * 0 on success, -1 on failure * %DESCRIPTION: * Handles an option ***********************************************************************/ static int handle_option(EventSelector *es, char const *name, char const *value) { if (option_context_fn) { return option_context_fn(es, name, value); } return l2tp_option_set(es, name, value, global_opts); }
/********************************************************************** * %FUNCTION: peer_process_option * %ARGUMENTS: * es -- event selector * name, value -- name and value of option * %RETURNS: * 0 on success, -1 on failure * %DESCRIPTION: * Processes an option in the "peer" section ***********************************************************************/ static int peer_process_option(EventSelector *es, char const *name, char const *value) { l2tp_peer *peer; /* Special cases: begin and end */ if (!strcmp(name, "*begin*")) { /* Switching in to peer context */ memset(&prototype, 0, sizeof(prototype)); prototype.mask_bits = 32; prototype.validate_peer_ip = 1; port = 1701; return 0; } if (!strcmp(name, "*end*")) { /* Validate settings */ uint16_t u16 = (uint16_t) port; prototype.addr.sin_port = htons(u16); prototype.addr.sin_family = AF_INET; /* Allow non-authenticated tunnels if (!prototype.secret_len) { l2tp_set_errmsg("No secret supplied for peer"); return -1; } */ if (!prototype.lns_ops && !prototype.lac_ops) { l2tp_set_errmsg("You must enable at least one of lns-handler or lac-handler"); return -1; } /* Add the peer */ peer = l2tp_peer_insert(&prototype.addr); if (!peer) return -1; peer->mask_bits = prototype.mask_bits; memcpy(&peer->hostname,&prototype.hostname, sizeof(prototype.hostname)); peer->hostname_len = prototype.hostname_len; memcpy(&peer->peername,&prototype.peername, sizeof(prototype.peername)); peer->peername_len = prototype.peername_len; memcpy(&peer->secret, &prototype.secret, MAX_SECRET_LEN); peer->secret_len = prototype.secret_len; peer->lns_ops = prototype.lns_ops; memcpy(&peer->lns_options,&prototype.lns_options,sizeof(prototype.lns_options)); peer->lac_ops = prototype.lac_ops; memcpy(&peer->lac_options,&prototype.lac_options,sizeof(prototype.lac_options)); peer->hide_avps = prototype.hide_avps; peer->retain_tunnel = prototype.retain_tunnel; peer->persist = prototype.persist; peer->holdoff = prototype.holdoff; peer->maxfail = prototype.maxfail; peer->fail = 0; peer->validate_peer_ip = prototype.validate_peer_ip; return 0; } /* Process option */ return l2tp_option_set(es, name, value, peer_opts); }