]> git.ipfire.org Git - people/stevee/network.git/blob - network
DNS: Add RDNSS functionality.
[people/stevee/network.git] / network
1 #!/bin/bash
2 ###############################################################################
3 # #
4 # IPFire.org - A linux based firewall #
5 # Copyright (C) 2010 Michael Tremer & Christian Schmidt #
6 # #
7 # This program is free software: you can redistribute it and/or modify #
8 # it under the terms of the GNU General Public License as published by #
9 # the Free Software Foundation, either version 3 of the License, or #
10 # (at your option) any later version. #
11 # #
12 # This program is distributed in the hope that it will be useful, #
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15 # GNU General Public License for more details. #
16 # #
17 # You should have received a copy of the GNU General Public License #
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. #
19 # #
20 ###############################################################################
21
22 # Parse the command line
23 while [ $# -gt 0 ]; do
24 case "${1}" in
25 -d|--debug)
26 DEBUG=1
27 ;;
28 *)
29 action=${1}
30 ;;
31 esac
32 shift
33 [ -n "${action}" ] && break
34 done
35
36 . /usr/lib/network/functions
37
38 function cli_config() {
39 if cli_help_requested $@; then
40 cli_show_man network-config
41 exit ${EXIT_OK}
42 fi
43
44 if [ -n "${1}" ]; then
45 config_set $@
46 network_config_write
47 else
48 network_config_print
49 fi
50 }
51
52 function cli_device() {
53 local device=${1}
54 local action=${2}
55 shift 2
56
57 if ! isset device; then
58 cli_show_man network-device
59 return ${EXIT_ERROR}
60 fi
61
62 assert device_exists ${device}
63
64 case "${action}" in
65 discover)
66 cli_device_discover ${device} $@
67 ;;
68 status)
69 cli_device_status ${device}
70 ;;
71 *)
72 cli_show_man network-device
73 ;;
74 esac
75
76 return ${EXIT_OK}
77 }
78
79 function cli_device_status() {
80 local device=${1}
81 assert device_exists ${device}
82
83 # Save the type of the device for later.
84 local type=$(device_get_type ${device})
85
86 cli_headline 1 "Device status: ${device}"
87 cli_print_fmt1 1 "Name" "${device}"
88
89 # Print the device status.
90 device_is_up ${device} &>/dev/null
91 local status=$?
92
93 case "${status}" in
94 ${EXIT_TRUE})
95 status="${COLOUR_GREEN}UP${COLOUR_NORMAL}"
96 ;;
97 ${EXIT_FALSE})
98 status="${COLOUR_RED}DOWN${COLOUR_NORMAL}"
99 ;;
100 esac
101
102 cli_print_fmt1 1 "Status" "${status}"
103 cli_print_fmt1 1 "Type" "${type}"
104 cli_print_fmt1 1 "Address" "$(device_get_address ${device})"
105 cli_space
106
107 # Print the link speed for ethernet devices.
108 case "${type}" in
109 ethernet)
110 cli_print_fmt1 1 "Link" \
111 "$(device_get_speed ${device}) MBit/s $(device_get_duplex ${device}) duplex"
112 ;;
113 esac
114
115 cli_print_fmt1 1 "MTU" "$(device_get_mtu ${device})"
116 cli_space
117
118 # Print device statistics.
119 cli_device_stats 2 ${device}
120
121 # Print some more information.
122 device_has_carrier ${device} &>/dev/null
123 cli_print_fmt1 1 "Has carrier?" "$(cli_print_bool $?)"
124
125 device_is_promisc ${device} &>/dev/null
126 cli_print_fmt1 1 "Promisc" "$(cli_print_bool $?)"
127 cli_space
128
129 # Print all virtual devices.
130 local virtuals=$(device_get_virtuals ${device})
131 if [ -n "${virtuals}" ]; then
132 cli_headline 2 "Virtual devices"
133
134 local virtual
135 for virtual in ${virtuals}; do
136 cli_print 2 "* %-6s - %s" "${virtual}" "$(device_get_address ${virtual})"
137 done
138 cli_space
139 fi
140
141 }
142
143 function cli_device_discover() {
144 local device=${1}
145 shift
146
147 local device_type=$(device_get_type ${device})
148 if [ "${device_type}" != "real" ]; then
149 return ${EXIT_OK}
150 fi
151
152 local raw
153
154 while [ $# -gt 0 ]; do
155 case "${1}" in
156 --raw)
157 raw=1
158 ;;
159 esac
160 shift
161 done
162
163 local up
164 device_is_up ${device} && up=1
165 device_set_up ${device}
166
167 enabled raw || echo "${device}"
168
169 local hook
170 local out
171 local ret
172 for hook in $(hook_zone_get_all); do
173 out=$(hook_zone_exec ${hook} discover ${device})
174 ret=$?
175
176 [ ${ret} -eq ${DISCOVER_NOT_SUPPORTED} ] && continue
177
178 if enabled raw; then
179 case "${ret}" in
180 ${DISCOVER_OK})
181 echo "${hook}: OK"
182 local line
183 while read line; do
184 echo "${hook}: ${line}"
185 done <<<"${out}"
186 ;;
187
188 ${DISCOVER_ERROR})
189 echo "${hook}: FAILED"
190 ;;
191 esac
192 else
193 case "${ret}" in
194 ${DISCOVER_OK})
195 echo " ${hook} was successful."
196 local line
197 while read line; do
198 echo " ${line}"
199 done <<<"${out}"
200 ;;
201
202 ${DISCOVER_ERROR})
203 echo " ${hook} failed."
204 ;;
205 esac
206 fi
207 done
208
209 echo # New line
210
211 [ "${up}" = "1" ] || device_set_down ${device}
212 }
213
214 function cli_hostname() {
215 if cli_help_requested $@; then
216 cli_show_man network
217 exit ${EXIT_OK}
218 fi
219
220 local hostname=${1}
221
222 if [ -n "${hostname}" ]; then
223 config_hostname ${hostname}
224 log INFO "Hostname was set to '${hostname}'."
225 log INFO "Changes do only take affect after reboot."
226 exit ${EXIT_OK}
227 fi
228
229 echo "$(config_hostname)"
230 exit ${EXIT_OK}
231 }
232
233 function cli_port() {
234 if cli_help_requested $@; then
235 cli_show_man network-port
236 exit ${EXIT_OK}
237 fi
238
239 local action
240 local port
241
242 if port_exists ${1}; then
243 port=${1}
244 action=${2}
245 shift 2
246
247 # Action aliases
248 case "${action}" in
249 start)
250 action="up"
251 ;;
252 stop)
253 action="down"
254 ;;
255 show)
256 action="status"
257 ;;
258 esac
259
260 case "${action}" in
261 edit|up|down|status)
262 port_${action} ${port} $@
263 ;;
264 *)
265 error "Unrecognized argument: ${action}"
266 exit ${EXIT_ERROR}
267 ;;
268 esac
269 else
270 action=${1}
271 shift
272
273 case "${action}" in
274 create|destroy)
275 port_${action} $@
276 ;;
277 *)
278 error "Unrecognized argument: ${action}"
279 exit ${EXIT_ERROR}
280 ;;
281 esac
282 fi
283 }
284
285 function cli_zone() {
286 if cli_help_requested $@; then
287 cli_show_man network-zone
288 exit ${EXIT_OK}
289 fi
290
291 local action
292 local zone
293
294 if zone_name_is_valid ${1}; then
295 zone=${1}
296 action=${2}
297 shift 2
298
299 # Action aliases
300 case "${action}" in
301 start)
302 action="up"
303 ;;
304 stop)
305 action="down"
306 ;;
307 show)
308 action="status"
309 ;;
310 esac
311
312 case "${action}" in
313 config|down|edit|port|status|up)
314 zone_${action} ${zone} $@
315 ;;
316 *)
317 error "Unrecognized argument: ${action}"
318 cli_show_man network-zone
319 exit ${EXIT_ERROR}
320 ;;
321 esac
322 else
323 action=${1}
324 shift
325
326 case "${action}" in
327 create)
328 zone_${action} $@
329 ;;
330 remove)
331 cli_zone_remove $@
332 ;;
333 list-hooks)
334 cli_list_hooks zone $@
335 ;;
336 ""|*)
337 if [ -n "${action}" ]; then
338 error "Unrecognized argument: '${action}'"
339 echo
340 fi
341
342 cli_show_man network-zone
343 exit ${EXIT_ERROR}
344 ;;
345 esac
346 fi
347 }
348
349 # Removes a zone either immediately, if it is currently down,
350 # or adds a tag that the removal will be done when the zone
351 # is brought down the next time.
352 function cli_zone_remove() {
353 if cli_help_requested $@; then
354 cli_show_man network-zone
355 exit ${EXIT_OK}
356 fi
357
358 local zone=${1}
359 assert zone_exists ${zone}
360
361 if zone_is_up ${zone}; then
362 echo "Zone '${zone}' is up and will be removed when it goes down the next time."
363 zone_remove ${zone}
364 else
365 echo "Removing zone '${zone}' now..."
366 zone_remove_now ${zone}
367 fi
368
369 exit ${EXIT_OK}
370 }
371
372 function cli_list_hooks() {
373 local type=${1}
374 shift
375
376 if cli_help_requested $@; then
377 cli_show_man network-zone
378 exit ${EXIT_OK}
379 fi
380
381 local hook_dir=$(hook_dir ${type})
382 local hook
383
384 for hook in ${hook_dir}/*; do
385 hook=$(basename ${hook})
386 if hook_exists ${type} ${hook}; then
387 echo "${hook}"
388 fi
389 done | sort -u
390 }
391
392 function cli_start() {
393 if cli_help_requested $@; then
394 cli_show_man network
395 exit ${EXIT_OK}
396 fi
397
398 local zones=$(zones_get $@)
399
400 local zone
401 for zone in ${zones}; do
402 zone_start ${zone} &
403 done
404
405 wait # until everything is settled
406 }
407
408 function cli_stop() {
409 if cli_help_requested $@; then
410 cli_show_man network
411 exit ${EXIT_OK}
412 fi
413
414 local zones=$(zones_get $@)
415
416 local zone
417 for zone in ${zones}; do
418 zone_stop ${zone} &
419 done
420
421 wait # until everything is settled
422 }
423
424 function cli_restart() {
425 if cli_help_requested $@; then
426 cli_show_man network
427 exit ${EXIT_OK}
428 fi
429
430 cli_stop $@
431
432 # Give the system some time to calm down
433 sleep ${TIMEOUT_RESTART}
434
435 cli_start $@
436 }
437
438 function cli_status() {
439 if cli_help_requested $@; then
440 cli_show_man network
441 exit ${EXIT_OK}
442 fi
443
444 # When dumping status information, the debug
445 # mode clutters the console which is not what we want.
446 # Logging on the console is disabled for a short time.
447 local log_disable_stdout=${LOG_DISABLE_STDOUT}
448 LOG_DISABLE_STDOUT="true"
449
450 local zones=$(zones_get $@)
451
452 local zone
453 for zone in ${zones}; do
454 zone_status ${zone}
455 done
456
457 # Reset logging.
458 LOG_DISABLE_STDOUT=${log_disable_stdout}
459 }
460
461 function cli_reset() {
462 if cli_help_requested $@; then
463 cli_show_man network
464 exit ${EXIT_OK}
465 fi
466
467 warning_log "Will reset the whole network configuration!!!"
468
469 # Force mode is disabled by default
470 local force=0
471
472 while [ $# -gt 0 ]; do
473 case "${1}" in
474 --force|-f)
475 force=1
476 ;;
477 esac
478 shift
479 done
480
481 # If we are not running in force mode, we ask the user if he does know
482 # what he is doing.
483 if ! enabled force; then
484 if ! cli_yesno "Do you really want to reset the whole network configuration?"; then
485 exit ${EXIT_ERROR}
486 fi
487 fi
488
489 local zone
490 for zone in $(zones_get --all); do
491 zone_remove ${zone}
492 done
493
494 local port
495 for port in $(ports_get --all); do
496 port_remove ${port}
497 done
498
499 # Flush all DNS servers.
500 dns_server_flush
501
502 # Re-run the initialization functions
503 init_run
504
505 exit ${EXIT_OK}
506 }
507
508 # Help function: will show the default man page to the user.
509 # Optionally, there are two arguments taken, the type of hook
510 # and which hook should be shown.
511 function cli_help() {
512 local type=${1}
513 local what=${2}
514
515 # Remove unknown types.
516 if ! listmatch ${type} zone port config; then
517 type=""
518 fi
519
520 # If no arguments were given, we will show the default page.
521 if [ -z "${type}" ]; then
522 cli_show_man network
523 return ${EXIT_OK}
524 fi
525
526 if ! hook_exists ${type} ${what}; then
527 error "Hook of type '${type}' and name '${what}' could not be found."
528 exit "${EXIT_ERROR}"
529 fi
530
531 hook_exec ${type} ${what} help
532 }
533
534 function cli_dns() {
535 if cli_help_requested $@; then
536 cli_show_man network-dns
537 exit ${EXIT_OK}
538 fi
539
540 # Get the command.
541 local cmd=${1}; shift
542 if [ -z "${cmd}" ]; then
543 cli_show_man network-dns
544 exit ${EXIT_ERROR}
545 fi
546
547 # Get the new server to process (if any).
548 local server=${1}
549 local priority=${2}
550
551 case "${cmd}" in
552 list)
553 __dns_server_println "SERVER" "PRIORITY"
554 dns_server_list
555 exit ${EXIT_OK}
556 ;;
557 add)
558 log INFO "Adding new DNS server: ${server}"
559 dns_server_add ${server} ${priority}
560 ;;
561 remove)
562 log INFO "Removing DNS server: ${server}"
563 dns_server_remove ${server} ${priority}
564 ;;
565 update)
566 # Just run the update afterwards.
567 ;;
568 *)
569 error "No such command: ${cmd}"
570 exit ${EXIT_ERROR}
571 esac
572
573 # Update the local DNS configuration after changes have been made.
574 dns_generate_resolvconf
575 radvd_update
576
577 exit ${EXIT_OK}
578 }
579
580 # Process the given action
581 case "${action}" in
582 init)
583 init_run
584 ;;
585
586 config|hostname|port|device|zone|start|stop|restart|status|reset|dns)
587 cli_${action} $@
588 ;;
589
590 ""|help|--help|-h)
591 cli_help $@
592 ;;
593
594 *)
595 error "Invalid command given: ${action}"
596 cli_usage "network help"
597 exit ${EXIT_CONF_ERROR}
598 ;;
599 esac
600
601 exit ${EXIT_OK}