]>
Commit | Line | Data |
---|---|---|
5b20e43a MT |
1 | #!/bin/bash |
2 | ############################################################################### | |
3 | # # | |
4 | # IPFire.org - A linux based firewall # | |
1848564d | 5 | # Copyright (C) 2010 Michael Tremer & Christian Schmidt # |
5b20e43a MT |
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 | ||
1848564d MT |
22 | # Parse the command line |
23 | while [ $# -gt 0 ]; do | |
24 | case "${1}" in | |
25 | -d|--debug) | |
26 | DEBUG=1 | |
5b20e43a | 27 | ;; |
1848564d MT |
28 | *) |
29 | action=${1} | |
5b20e43a | 30 | ;; |
5b20e43a | 31 | esac |
5b20e43a | 32 | shift |
1848564d | 33 | [ -n "${action}" ] && break |
5b20e43a MT |
34 | done |
35 | ||
3647b19f MT |
36 | . /usr/lib/network/functions |
37 | ||
9111eb72 MT |
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 | ||
ec63256a MT |
57 | if ! isset device; then |
58 | cli_show_man network-device | |
9111eb72 MT |
59 | return ${EXIT_ERROR} |
60 | fi | |
61 | ||
ec63256a MT |
62 | assert device_exists ${device} |
63 | ||
9111eb72 MT |
64 | case "${action}" in |
65 | discover) | |
9111eb72 MT |
66 | cli_device_discover ${device} $@ |
67 | ;; | |
ec63256a MT |
68 | status) |
69 | cli_device_status ${device} | |
9111eb72 MT |
70 | ;; |
71 | *) | |
72 | cli_show_man network-device | |
73 | ;; | |
74 | esac | |
ec63256a MT |
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 | # This section will print statistical data from the device. | |
119 | local packets bytes errors | |
120 | ||
121 | cli_headline 2 "Statistics" | |
122 | local format="%-10s %9d packets %6s (%d errors)" | |
123 | ||
124 | # RX | |
125 | packets=$(device_get_rx_packets ${device}) | |
126 | bytes=$(device_get_rx_bytes ${device}) | |
127 | errors=$(device_get_rx_errors ${device}) | |
128 | ||
129 | cli_print 2 "${format}" "Received" "${packets}" "$(beautify_bytes ${bytes})" "${errors}" | |
130 | ||
131 | # TX | |
132 | packets=$(device_get_tx_packets ${device}) | |
133 | bytes=$(device_get_tx_bytes ${device}) | |
134 | errors=$(device_get_tx_errors ${device}) | |
135 | ||
136 | cli_print 2 "${format}" "Sent" "${packets}" "$(beautify_bytes ${bytes})" "${errors}" | |
137 | cli_space | |
138 | ||
139 | # Print some more information. | |
140 | device_has_carrier ${device} &>/dev/null | |
141 | cli_print_fmt1 1 "Has carrier?" "$(cli_print_bool $?)" | |
142 | ||
143 | device_is_promisc ${device} &>/dev/null | |
144 | cli_print_fmt1 1 "Promisc" "$(cli_print_bool $?)" | |
145 | cli_space | |
146 | ||
147 | # Print all virtual devices. | |
148 | local virtuals=$(device_get_virtuals ${device}) | |
149 | if [ -n "${virtuals}" ]; then | |
150 | cli_headline 2 "Virtual devices" | |
151 | ||
152 | local virtual | |
153 | for virtual in ${virtuals}; do | |
154 | cli_print 2 "* %-6s - %s" "${virtual}" "$(device_get_address ${virtual})" | |
155 | done | |
156 | cli_space | |
157 | fi | |
158 | ||
9111eb72 MT |
159 | } |
160 | ||
161 | function cli_device_discover() { | |
162 | local device=${1} | |
163 | shift | |
164 | ||
165 | local device_type=$(device_get_type ${device}) | |
166 | if [ "${device_type}" != "real" ]; then | |
167 | return ${EXIT_OK} | |
168 | fi | |
169 | ||
170 | local raw | |
171 | ||
172 | while [ $# -gt 0 ]; do | |
173 | case "${1}" in | |
174 | --raw) | |
175 | raw=1 | |
176 | ;; | |
177 | esac | |
178 | shift | |
179 | done | |
180 | ||
181 | local up | |
182 | device_is_up ${device} && up=1 | |
183 | device_set_up ${device} | |
184 | ||
185 | enabled raw || echo "${device}" | |
186 | ||
187 | local hook | |
188 | local out | |
189 | local ret | |
190 | for hook in $(hook_zone_get_all); do | |
191 | out=$(hook_zone_exec ${hook} discover ${device}) | |
192 | ret=$? | |
193 | ||
194 | [ ${ret} -eq ${DISCOVER_NOT_SUPPORTED} ] && continue | |
195 | ||
196 | if enabled raw; then | |
197 | case "${ret}" in | |
198 | ${DISCOVER_OK}) | |
199 | echo "${hook}: OK" | |
200 | local line | |
201 | while read line; do | |
202 | echo "${hook}: ${line}" | |
203 | done <<<"${out}" | |
204 | ;; | |
205 | ||
206 | ${DISCOVER_ERROR}) | |
207 | echo "${hook}: FAILED" | |
208 | ;; | |
209 | esac | |
210 | else | |
211 | case "${ret}" in | |
212 | ${DISCOVER_OK}) | |
213 | echo " ${hook} was successful." | |
214 | local line | |
215 | while read line; do | |
216 | echo " ${line}" | |
217 | done <<<"${out}" | |
218 | ;; | |
219 | ||
220 | ${DISCOVER_ERROR}) | |
221 | echo " ${hook} failed." | |
222 | ;; | |
223 | esac | |
224 | fi | |
225 | done | |
226 | ||
227 | echo # New line | |
228 | ||
229 | [ "${up}" = "1" ] || device_set_down ${device} | |
230 | } | |
231 | ||
232 | function cli_hostname() { | |
233 | if cli_help_requested $@; then | |
234 | cli_show_man network | |
235 | exit ${EXIT_OK} | |
236 | fi | |
237 | ||
238 | local hostname=${1} | |
239 | ||
240 | if [ -n "${hostname}" ]; then | |
241 | config_hostname ${hostname} | |
242 | log INFO "Hostname was set to '${hostname}'." | |
243 | log INFO "Changes do only take affect after reboot." | |
244 | exit ${EXIT_OK} | |
245 | fi | |
246 | ||
247 | echo "$(config_hostname)" | |
248 | exit ${EXIT_OK} | |
249 | } | |
250 | ||
251 | function cli_port() { | |
252 | if cli_help_requested $@; then | |
253 | cli_show_man network-port | |
254 | exit ${EXIT_OK} | |
255 | fi | |
256 | ||
257 | local action | |
258 | local port | |
259 | ||
260 | if port_exists ${1}; then | |
261 | port=${1} | |
262 | action=${2} | |
263 | shift 2 | |
264 | ||
265 | # Action aliases | |
266 | case "${action}" in | |
267 | start) | |
268 | action="up" | |
269 | ;; | |
270 | stop) | |
271 | action="down" | |
272 | ;; | |
273 | show) | |
274 | action="status" | |
275 | ;; | |
276 | esac | |
277 | ||
278 | case "${action}" in | |
279 | edit|up|down|status) | |
280 | port_${action} ${port} $@ | |
281 | ;; | |
282 | *) | |
283 | error "Unrecognized argument: ${action}" | |
284 | exit ${EXIT_ERROR} | |
285 | ;; | |
286 | esac | |
287 | else | |
288 | action=${1} | |
289 | shift | |
290 | ||
291 | case "${action}" in | |
292 | create|destroy) | |
293 | port_${action} $@ | |
294 | ;; | |
295 | *) | |
296 | error "Unrecognized argument: ${action}" | |
297 | exit ${EXIT_ERROR} | |
298 | ;; | |
299 | esac | |
300 | fi | |
301 | } | |
302 | ||
303 | function cli_zone() { | |
304 | if cli_help_requested $@; then | |
305 | cli_show_man network-zone | |
306 | exit ${EXIT_OK} | |
307 | fi | |
308 | ||
309 | local action | |
310 | local zone | |
311 | ||
312 | if zone_name_is_valid ${1}; then | |
313 | zone=${1} | |
314 | action=${2} | |
315 | shift 2 | |
316 | ||
317 | # Action aliases | |
318 | case "${action}" in | |
319 | start) | |
320 | action="up" | |
321 | ;; | |
322 | stop) | |
323 | action="down" | |
324 | ;; | |
325 | show) | |
326 | action="status" | |
327 | ;; | |
328 | esac | |
329 | ||
330 | case "${action}" in | |
331 | config|down|edit|port|status|up) | |
332 | zone_${action} ${zone} $@ | |
333 | ;; | |
334 | *) | |
335 | error "Unrecognized argument: ${action}" | |
336 | cli_show_man network-zone | |
337 | exit ${EXIT_ERROR} | |
338 | ;; | |
339 | esac | |
340 | else | |
341 | action=${1} | |
342 | shift | |
343 | ||
344 | case "${action}" in | |
345 | create) | |
346 | zone_${action} $@ | |
347 | ;; | |
348 | remove) | |
349 | cli_zone_remove $@ | |
350 | ;; | |
351 | list-hooks) | |
352 | cli_list_hooks zone $@ | |
353 | ;; | |
354 | ""|*) | |
355 | if [ -n "${action}" ]; then | |
356 | error "Unrecognized argument: '${action}'" | |
357 | echo | |
358 | fi | |
359 | ||
360 | cli_show_man network-zone | |
361 | exit ${EXIT_ERROR} | |
362 | ;; | |
363 | esac | |
364 | fi | |
365 | } | |
366 | ||
367 | # Removes a zone either immediately, if it is currently down, | |
368 | # or adds a tag that the removal will be done when the zone | |
369 | # is brought down the next time. | |
370 | function cli_zone_remove() { | |
371 | if cli_help_requested $@; then | |
372 | cli_show_man network-zone | |
373 | exit ${EXIT_OK} | |
374 | fi | |
375 | ||
376 | local zone=${1} | |
377 | assert zone_exists ${zone} | |
378 | ||
379 | if zone_is_up ${zone}; then | |
380 | echo "Zone '${zone}' is up and will be removed when it goes down the next time." | |
381 | zone_remove ${zone} | |
382 | else | |
383 | echo "Removing zone '${zone}' now..." | |
384 | zone_remove_now ${zone} | |
385 | fi | |
386 | ||
387 | exit ${EXIT_OK} | |
388 | } | |
389 | ||
390 | function cli_list_hooks() { | |
391 | local type=${1} | |
392 | shift | |
393 | ||
394 | if cli_help_requested $@; then | |
395 | cli_show_man network-zone | |
396 | exit ${EXIT_OK} | |
397 | fi | |
398 | ||
399 | local hook_dir=$(hook_dir ${type}) | |
400 | local hook | |
401 | ||
402 | for hook in ${hook_dir}/*; do | |
403 | hook=$(basename ${hook}) | |
404 | if hook_exists ${type} ${hook}; then | |
405 | echo "${hook}" | |
406 | fi | |
407 | done | sort -u | |
408 | } | |
409 | ||
410 | function cli_start() { | |
411 | if cli_help_requested $@; then | |
412 | cli_show_man network | |
413 | exit ${EXIT_OK} | |
414 | fi | |
415 | ||
416 | local zones=$(zones_get $@) | |
417 | ||
418 | local zone | |
419 | for zone in ${zones}; do | |
420 | zone_start ${zone} & | |
421 | done | |
422 | ||
423 | wait # until everything is settled | |
424 | } | |
425 | ||
426 | function cli_stop() { | |
427 | if cli_help_requested $@; then | |
428 | cli_show_man network | |
429 | exit ${EXIT_OK} | |
430 | fi | |
431 | ||
432 | local zones=$(zones_get $@) | |
433 | ||
434 | local zone | |
435 | for zone in ${zones}; do | |
436 | zone_stop ${zone} & | |
437 | done | |
438 | ||
439 | wait # until everything is settled | |
440 | } | |
441 | ||
442 | function cli_restart() { | |
443 | if cli_help_requested $@; then | |
444 | cli_show_man network | |
445 | exit ${EXIT_OK} | |
446 | fi | |
447 | ||
448 | cli_stop $@ | |
449 | ||
450 | # Give the system some time to calm down | |
451 | sleep ${TIMEOUT_RESTART} | |
452 | ||
453 | cli_start $@ | |
454 | } | |
455 | ||
456 | function cli_status() { | |
457 | if cli_help_requested $@; then | |
458 | cli_show_man network | |
459 | exit ${EXIT_OK} | |
460 | fi | |
461 | ||
462 | # When dumping status information, the debug | |
463 | # mode clutters the console which is not what we want. | |
464 | # Logging on the console is disabled for a short time. | |
465 | local log_disable_stdout=${LOG_DISABLE_STDOUT} | |
466 | LOG_DISABLE_STDOUT="true" | |
467 | ||
468 | local zones=$(zones_get $@) | |
469 | ||
470 | local zone | |
471 | for zone in ${zones}; do | |
472 | zone_status ${zone} | |
473 | done | |
474 | ||
475 | # Reset logging. | |
476 | LOG_DISABLE_STDOUT=${log_disable_stdout} | |
477 | } | |
478 | ||
479 | function cli_reset() { | |
480 | if cli_help_requested $@; then | |
481 | cli_show_man network | |
482 | exit ${EXIT_OK} | |
483 | fi | |
484 | ||
485 | warning_log "Will reset the whole network configuration!!!" | |
486 | ||
487 | # Force mode is disabled by default | |
488 | local force=0 | |
489 | ||
490 | while [ $# -gt 0 ]; do | |
491 | case "${1}" in | |
492 | --force|-f) | |
493 | force=1 | |
494 | ;; | |
495 | esac | |
496 | shift | |
497 | done | |
498 | ||
499 | # If we are not running in force mode, we ask the user if he does know | |
500 | # what he is doing. | |
501 | if ! enabled force; then | |
502 | if ! cli_yesno "Do you really want to reset the whole network configuration?"; then | |
503 | exit ${EXIT_ERROR} | |
504 | fi | |
505 | fi | |
506 | ||
507 | local zone | |
508 | for zone in $(zones_get --all); do | |
509 | zone_remove ${zone} | |
510 | done | |
511 | ||
512 | local port | |
513 | for port in $(ports_get --all); do | |
514 | port_remove ${port} | |
515 | done | |
516 | ||
517 | # Re-run the initialization functions | |
518 | init_run | |
519 | ||
520 | exit ${EXIT_OK} | |
521 | } | |
522 | ||
85afd775 MT |
523 | # Help function: will show the default man page to the user. |
524 | # Optionally, there are two arguments taken, the type of hook | |
525 | # and which hook should be shown. | |
526 | function cli_help() { | |
527 | local type=${1} | |
528 | local what=${2} | |
529 | ||
530 | # Remove unknown types. | |
531 | if ! listmatch ${type} zone port config; then | |
532 | type="" | |
533 | fi | |
534 | ||
535 | # If no arguments were given, we will show the default page. | |
536 | if [ -z "${type}" ]; then | |
537 | cli_show_man network | |
538 | return ${EXIT_OK} | |
539 | fi | |
540 | ||
541 | if ! hook_exists ${type} ${what}; then | |
542 | error "Hook of type '${type}' and name '${what}' could not be found." | |
543 | exit "${EXIT_ERROR}" | |
544 | fi | |
545 | ||
546 | hook_exec ${type} ${what} help | |
547 | } | |
548 | ||
1848564d MT |
549 | # Process the given action |
550 | case "${action}" in | |
b8357295 MT |
551 | init) |
552 | init_run | |
553 | ;; | |
554 | ||
de28a630 | 555 | config|hostname|port|device|zone|start|stop|restart|status|reset) |
0a79ea02 | 556 | cli_${action} $@ |
1848564d MT |
557 | ;; |
558 | ||
fe4555b5 | 559 | ""|help|--help|-h) |
85afd775 | 560 | cli_help $@ |
1848564d | 561 | ;; |
fe4555b5 | 562 | |
1848564d | 563 | *) |
fe4555b5 | 564 | error "Invalid command given: ${action}" |
de28a630 | 565 | cli_usage "network help" |
1848564d | 566 | exit ${EXIT_CONF_ERROR} |
fe4555b5 | 567 | ;; |
1848564d | 568 | esac |
85afd775 MT |
569 | |
570 | exit ${EXIT_OK} |