Annotation of embedaddon/mtr/packet/packet.c, revision 1.1
1.1 ! misho 1: /*
! 2: mtr -- a network diagnostic tool
! 3: Copyright (C) 2016 Matt Kimball
! 4:
! 5: This program is free software; you can redistribute it and/or modify
! 6: it under the terms of the GNU General Public License version 2 as
! 7: published by the Free Software Foundation.
! 8:
! 9: This program is distributed in the hope that it will be useful,
! 10: but WITHOUT ANY WARRANTY; without even the implied warranty of
! 11: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! 12: GNU General Public License for more details.
! 13:
! 14: You should have received a copy of the GNU General Public License
! 15: along with this program; if not, write to the Free Software
! 16: Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
! 17: */
! 18:
! 19: #include "config.h"
! 20:
! 21: #include <errno.h>
! 22: #include <stdio.h>
! 23: #include <stdlib.h>
! 24: #include <string.h>
! 25: #include <unistd.h>
! 26:
! 27: #ifdef HAVE_LIBCAP
! 28: #include <sys/capability.h>
! 29: #endif
! 30:
! 31: #include "wait.h"
! 32:
! 33: /* Drop SUID privileges. To be used after accquiring raw sockets. */
! 34: static
! 35: int drop_elevated_permissions(
! 36: void)
! 37: {
! 38: #ifdef HAVE_LIBCAP
! 39: cap_t cap;
! 40: #endif
! 41:
! 42: /* Drop any suid permissions granted */
! 43: if (setgid(getgid()) || setuid(getuid())) {
! 44: return -1;
! 45: }
! 46:
! 47: if (geteuid() != getuid() || getegid() != getgid()) {
! 48: return -1;
! 49: }
! 50:
! 51: /*
! 52: Drop all process capabilities.
! 53: This will revoke anything granted by a commandline 'setcap'
! 54: */
! 55: #ifdef HAVE_LIBCAP
! 56: cap = cap_get_proc();
! 57: if (cap == NULL) {
! 58: return -1;
! 59: }
! 60: if (cap_clear(cap)) {
! 61: return -1;
! 62: }
! 63: if (cap_set_proc(cap)) {
! 64: return -1;
! 65: }
! 66: #endif
! 67:
! 68: return 0;
! 69: }
! 70:
! 71: int main(
! 72: int argc,
! 73: char **argv)
! 74: {
! 75: bool command_pipe_open;
! 76: struct command_buffer_t command_buffer;
! 77: struct net_state_t net_state;
! 78:
! 79: /*
! 80: To minimize security risk, the only thing done prior to
! 81: dropping SUID should be opening the network state for
! 82: raw sockets.
! 83: */
! 84: init_net_state_privileged(&net_state);
! 85: if (drop_elevated_permissions()) {
! 86: perror("Unable to drop elevated permissions");
! 87: exit(EXIT_FAILURE);
! 88: }
! 89: init_net_state(&net_state);
! 90:
! 91: init_command_buffer(&command_buffer, fileno(stdin));
! 92:
! 93: command_pipe_open = true;
! 94:
! 95: /*
! 96: Dispatch commands and respond to probe replies until the
! 97: command stream is closed.
! 98: */
! 99: while (true) {
! 100: /* Ensure any responses are written before waiting */
! 101: fflush(stdout);
! 102: wait_for_activity(&command_buffer, &net_state);
! 103:
! 104: /*
! 105: Receive replies first so that the timestamps are as
! 106: close to the response arrival time as possible.
! 107: */
! 108: receive_replies(&net_state);
! 109:
! 110: if (command_pipe_open) {
! 111: if (read_commands(&command_buffer)) {
! 112: if (errno == EPIPE) {
! 113: command_pipe_open = false;
! 114: }
! 115: }
! 116: }
! 117:
! 118: check_probe_timeouts(&net_state);
! 119:
! 120: /*
! 121: Dispatch commands late so that the window between probe
! 122: departure and arriving replies is as small as possible.
! 123: */
! 124: dispatch_buffer_commands(&command_buffer, &net_state);
! 125:
! 126: /*
! 127: If the command pipe has been closed, exit after all
! 128: in-flight probes have reported their status.
! 129: */
! 130: if (!command_pipe_open) {
! 131: if (net_state.outstanding_probe_count == 0) {
! 132: break;
! 133: }
! 134: }
! 135: }
! 136:
! 137: return 0;
! 138: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>