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