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