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