1 1.9 kefren /* $NetBSD: main.c,v 1.9 2013/07/31 06:58:23 kefren Exp $ */ 2 1.1 kefren 3 1.1 kefren /*- 4 1.1 kefren * Copyright (c) 2010 The NetBSD Foundation, Inc. 5 1.1 kefren * All rights reserved. 6 1.1 kefren * 7 1.1 kefren * This code is derived from software contributed to The NetBSD Foundation 8 1.1 kefren * by Mihai Chelaru <kefren (at) NetBSD.org> 9 1.1 kefren * 10 1.1 kefren * Redistribution and use in source and binary forms, with or without 11 1.1 kefren * modification, are permitted provided that the following conditions 12 1.1 kefren * are met: 13 1.1 kefren * 1. Redistributions of source code must retain the above copyright 14 1.1 kefren * notice, this list of conditions and the following disclaimer. 15 1.1 kefren * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 kefren * notice, this list of conditions and the following disclaimer in the 17 1.1 kefren * documentation and/or other materials provided with the distribution. 18 1.1 kefren * 19 1.1 kefren * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.1 kefren * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.1 kefren * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.1 kefren * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.1 kefren * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.1 kefren * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.1 kefren * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.1 kefren * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.1 kefren * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.1 kefren * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.1 kefren * POSSIBILITY OF SUCH DAMAGE. 30 1.1 kefren */ 31 1.1 kefren 32 1.1 kefren #include <netinet/in.h> 33 1.1 kefren #include <sys/stat.h> 34 1.1 kefren #include <sys/socket.h> 35 1.1 kefren #include <arpa/inet.h> 36 1.1 kefren 37 1.1 kefren #include <stdio.h> 38 1.1 kefren #include <stdlib.h> 39 1.1 kefren #include <strings.h> 40 1.1 kefren #include <unistd.h> 41 1.1 kefren 42 1.1 kefren #include "ldp.h" 43 1.1 kefren #include "ldp_command.h" 44 1.1 kefren #include "socketops.h" 45 1.1 kefren #include "tlv.h" 46 1.1 kefren #include "pdu.h" 47 1.1 kefren #include "fsm.h" 48 1.1 kefren #include "ldp_errors.h" 49 1.1 kefren #include "mpls_interface.h" 50 1.3 kefren #include "conffile.h" 51 1.1 kefren 52 1.3 kefren extern int ls; /* TCP listening socket */ 53 1.3 kefren extern int dont_catch; 54 1.3 kefren extern int command_port; 55 1.3 kefren extern int command_socket; 56 1.1 kefren 57 1.3 kefren extern int debug_f, warn_f, syslog_f; 58 1.1 kefren 59 1.3 kefren extern struct sockaddr mplssockaddr; 60 1.3 kefren extern struct in_addr conf_ldp_id; 61 1.1 kefren 62 1.1 kefren void print_usage(char *myself) 63 1.1 kefren { 64 1.4 wiz printf("\nUsage: %s [-DdfhW] [-c config_file] [-p port]\n\n", myself); 65 1.1 kefren } 66 1.1 kefren 67 1.1 kefren int 68 1.1 kefren main(int argc, char *argv[]) 69 1.1 kefren { 70 1.3 kefren int ch, forkres, dontfork = 0, cpf; 71 1.3 kefren char conffile[PATH_MAX + 1]; 72 1.1 kefren 73 1.3 kefren strlcpy(conffile, CONFFILE, sizeof(conffile)); 74 1.3 kefren while((ch = getopt(argc, argv, "c:dDfhp:W")) != -1) 75 1.1 kefren switch(ch) { 76 1.3 kefren case 'c': 77 1.3 kefren strlcpy(conffile, optarg, sizeof(conffile)); 78 1.3 kefren break; 79 1.2 wiz case 'D': 80 1.2 wiz debug_f = 1; 81 1.2 wiz break; 82 1.1 kefren case 'd': 83 1.1 kefren dont_catch = 1; 84 1.1 kefren break; 85 1.1 kefren case 'f': 86 1.1 kefren dontfork = 1; 87 1.1 kefren break; 88 1.1 kefren case 'p': 89 1.1 kefren if ((command_port = atoi(optarg)) < 1) { 90 1.1 kefren print_usage(argv[0]); 91 1.6 kefren return EXIT_FAILURE; 92 1.1 kefren } 93 1.1 kefren break; 94 1.1 kefren case 'W': 95 1.1 kefren warn_f = 1; 96 1.1 kefren break; 97 1.1 kefren case 'h': 98 1.1 kefren default: 99 1.1 kefren print_usage(argv[0]); 100 1.6 kefren return EXIT_FAILURE; 101 1.1 kefren break; 102 1.1 kefren } 103 1.3 kefren 104 1.3 kefren cpf = conf_parsefile(conffile); 105 1.3 kefren if (cpf < 0 && strcmp(conffile, CONFFILE)) { 106 1.3 kefren fatalp("Cannot parse config file: %s\n", conffile); 107 1.6 kefren return EXIT_FAILURE; 108 1.3 kefren } else if (cpf > 0) { 109 1.3 kefren fatalp("Cannot parse line %d in config file\n", cpf); 110 1.6 kefren return EXIT_FAILURE; 111 1.3 kefren } 112 1.3 kefren 113 1.1 kefren if (set_my_ldp_id()) { 114 1.1 kefren fatalp("Cannot set LDP ID\n"); 115 1.6 kefren return EXIT_FAILURE; 116 1.1 kefren } 117 1.3 kefren if (conf_ldp_id.s_addr != 0) 118 1.3 kefren strlcpy(my_ldp_id, inet_ntoa(conf_ldp_id), INET_ADDRSTRLEN); 119 1.3 kefren 120 1.1 kefren if (mplssockaddr.sa_len == 0) { 121 1.8 kefren fatalp("FATAL: Create an mpls interface using ifconfig\n" 122 1.8 kefren "e.g. ifconfig mpls0 create up\n"); 123 1.6 kefren return EXIT_FAILURE; 124 1.1 kefren } 125 1.1 kefren if (mpls_start_ldp() == -1) 126 1.6 kefren return EXIT_FAILURE; 127 1.1 kefren if (!strcmp(LDP_ID, "0.0.0.0")) { 128 1.1 kefren fatalp("Cannot set my LDP ID.\nAre you sure you've " 129 1.1 kefren "got a non-loopback INET interface UP ?\n"); 130 1.6 kefren return EXIT_FAILURE; 131 1.1 kefren } 132 1.1 kefren init_command_sockets(); 133 1.1 kefren if ((command_socket = create_command_socket(command_port)) < 1) { 134 1.1 kefren fatalp("Cannot create command socket\n"); 135 1.6 kefren return EXIT_FAILURE; 136 1.1 kefren } 137 1.7 kefren if (create_hello_sockets() != 0) { 138 1.1 kefren fatalp("Cannot create hello socket\n"); 139 1.6 kefren return EXIT_FAILURE; 140 1.1 kefren } 141 1.1 kefren 142 1.1 kefren ls = create_listening_socket(); 143 1.1 kefren 144 1.1 kefren if (ls < 0) { 145 1.1 kefren fatalp("Cannot create listening socket\n"); 146 1.6 kefren return EXIT_FAILURE; 147 1.1 kefren } 148 1.1 kefren 149 1.1 kefren if (dontfork == 1) 150 1.5 kefren return the_big_loop(); 151 1.1 kefren 152 1.1 kefren forkres = fork(); 153 1.1 kefren if (forkres == 0) { 154 1.1 kefren syslog_f = 1; 155 1.5 kefren return the_big_loop(); 156 1.1 kefren } 157 1.1 kefren if (forkres < 0) 158 1.1 kefren perror("fork"); 159 1.1 kefren 160 1.6 kefren return EXIT_SUCCESS; 161 1.1 kefren } 162