Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow -w to take paths containing date/time components when using -G #936

Open
rigtorp opened this issue Aug 24, 2021 · 9 comments
Open

Comments

@rigtorp
Copy link

rigtorp commented Aug 24, 2021

When using the -G option it can be useful to organize files by year/month/day by setting -w %Y/%m/%d/%Y%%m%dT%H%M%SZ.pcap. This will fail if any of the parent directories are missing.

We can add an option to make tcpdump create the parent directories as if mkdir -p $(dirname $file) is invoked before opening the file.

I have adapted the code from OpenBSD mkdir to do exactly this. It would need to be updated to use mkdirat instead if we want to support the tcpdump privilege separation.

// Equivalent of mkdir -p $(dirname $path)
// Adapted from OpenBSD's mkdir (bin/mkdir/mkdir.c)
static int mkpath(char *path, mode_t mode) {
  char *slash = path;

  for (;;) {
    slash += strspn(slash, "/");
    slash += strcspn(slash, "/");

    if (*slash == '\0') {
      // Don't create directory for filename part
      break;
    }
    *slash = '\0';

    if (mkdir(path, mode) == -1) {
      int mkdir_errno = errno;

      struct stat sb;
      if (stat(path, &sb) == -1) {
        // Not there; use mkdir()s errno
        errno = mkdir_errno;
        return -1;
      }
      if (!S_ISDIR(sb.st_mode)) {
        // Is there, but isn't a directory
        errno = ENOTDIR;
        return -1;
      }
    }

    *slash = '/';
  }

  return 0;
}
@infrastation
Copy link
Member

Alternatively, it would not be difficult to have a shell script that creates the directories before running tcpdump and makes sure the ownership and permissions are correct. Or a script that moves complete .pcap files to such directories when tcpdump is running (and maybe compresses them).

@infrastation
Copy link
Member

What would be the advantages of implementing this in the C code solution space instead of a shell script solution space?

@guyharris guyharris changed the title When writing to a file, optionally create missing parent directories Allow -w to take paths containing date/time components when using -G Nov 26, 2021
@rigtorp
Copy link
Author

rigtorp commented Nov 27, 2021

Convenience.

@guyharris
Copy link
Member

Without -G, it could just as well be done with a script.

With -G, the file name is already generated "in the C code solution space", by which "inside tcpdump" is presumably meant; this change allows the path name to be generated by tcpdump, without something external to tcpdump, such as a script running tcpdump, having to anticipate the directory paths that tcpdump will use and create them before tcpdump uses them.

Bear in mind that this would be a continuously-running tcpdump, so it can run across a day, month, or even year boundary.

(The original comment in the issue mentions that this is with -G.)

@infrastation
Copy link
Member

Well, then someone would need to make sure it works well with Capsicum, privileges dropping, signal handlers and whatever else happens to be involved.

@rigtorp
Copy link
Author

rigtorp commented Nov 29, 2021

Actually the only thing needed is to call that mkpath function I attached before trying to open a new file.

-G already doesn't work very well with privilege dropping, need to use openat to keep privs to write to the directory. I usually launch tcpdump from systemd instead as a specific user and letting systemd add the CAP_NET_RAW privilege before launching.

@rigtorp
Copy link
Author

rigtorp commented Dec 8, 2021

As an example here is a tool I use to record multicast UDP streams: https://rigtorp.se/udpcap.cpp (or in case first one is down https://gist.github.com/rigtorp/9544c98119b56d68814eb7b45758eb7a). It has this behavior of automatically creating missing directories.

@infrastation
Copy link
Member

I wonder why you did not make this a pull request.

@rigtorp
Copy link
Author

rigtorp commented Dec 10, 2021 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

3 participants