mirror of
https://git.savannah.gnu.org/git/inetutils.git
synced 2026-01-12 00:19:39 +08:00
131 lines
3.3 KiB
C
131 lines
3.3 KiB
C
/* addrpeek - testing service for Inetd: remote address, environment vars
|
|
Copyright (C) 2010-2025 Free Software Foundation, Inc.
|
|
|
|
This file is part of GNU Inetutils.
|
|
|
|
GNU Inetutils is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or (at
|
|
your option) any later version.
|
|
|
|
GNU Inetutils is distributed in the hope that it will be useful, but
|
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see `http://www.gnu.org/licenses/'. */
|
|
|
|
/* Written by Mats Erik Andersson. */
|
|
|
|
/* Addrpeek is a test client for examining Inetd, primarily TCP traffic.
|
|
* The client executes all those tasks that were listed as server
|
|
* arguments in the configuration file for Inetd:
|
|
*
|
|
* addr : Reply with "Your address is $IP."
|
|
* env : Reply with all known environment variables and their values.
|
|
*
|
|
* Reasonable entries in `inetf.conf' could be
|
|
*
|
|
* # Return numerical address of the calling client.
|
|
* #
|
|
* 7890 stream tcp nowait nobody /tmp/addrpeek addrpeek addr
|
|
* 7890 stream tcp6 nowait nobody /tmp/addrpeek addrpeek addr
|
|
* #
|
|
* # Display all environment variables in use, and append
|
|
* # the client's address at the end.
|
|
* #
|
|
* tcpmux stream tcp nowait nobody internal
|
|
* tcpmux stream tcp6 nowait nobody internal
|
|
* tcpmux/env stream tcp nowait nobody /tmp/addrpeek addrkeep env addr
|
|
*/
|
|
|
|
#include <config.h>
|
|
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/types.h>
|
|
#include <sys/socket.h>
|
|
#include <netinet/in.h>
|
|
#include <netdb.h>
|
|
#include <progname.h>
|
|
|
|
#ifndef SEPARATOR
|
|
# define SEPARATOR "\n"
|
|
#endif
|
|
|
|
static void
|
|
write_address (int fd)
|
|
{
|
|
int type;
|
|
size_t len;
|
|
socklen_t sslen;
|
|
char addr[INET6_ADDRSTRLEN], answer[128];
|
|
struct sockaddr_storage ss;
|
|
|
|
sslen = sizeof (type);
|
|
getsockopt (fd, SOL_SOCKET, SO_TYPE, &type, &sslen);
|
|
|
|
if (type == SOCK_STREAM)
|
|
{
|
|
sslen = sizeof (ss);
|
|
getpeername (fd, (struct sockaddr *) &ss, &sslen);
|
|
}
|
|
else if (type == SOCK_DGRAM)
|
|
{
|
|
sslen = sizeof (ss);
|
|
recvfrom (fd, answer, sizeof (answer), 0,
|
|
(struct sockaddr *) &ss, &sslen);
|
|
shutdown (fd, SHUT_RD);
|
|
}
|
|
else
|
|
return;
|
|
|
|
getnameinfo ((struct sockaddr *) &ss, sslen, addr, sizeof (addr),
|
|
NULL, 0, NI_NUMERICHOST);
|
|
|
|
len = snprintf (answer, sizeof (answer),
|
|
"Your address is %s." SEPARATOR, addr);
|
|
|
|
sendto (fd, answer, len, 0, (struct sockaddr *) &ss, sslen);
|
|
}
|
|
|
|
void
|
|
write_environment (int fd, char *envp[])
|
|
{
|
|
for (; *envp; ++envp)
|
|
{
|
|
write (fd, *envp, strlen (*envp));
|
|
write (fd, SEPARATOR, strlen (SEPARATOR));
|
|
}
|
|
}
|
|
|
|
int
|
|
main (int argc, char *argv[])
|
|
{
|
|
int j;
|
|
set_program_name (argv[0]);
|
|
for (j = 1; j < argc; ++j)
|
|
{
|
|
if (strncmp (argv[j], "addr", strlen ("addr")) == 0)
|
|
{
|
|
write_address (STDOUT_FILENO);
|
|
continue;
|
|
}
|
|
|
|
if (strncmp (argv[j], "env", strlen ("env")) == 0)
|
|
{
|
|
write_environment (STDOUT_FILENO, environ);
|
|
continue;
|
|
}
|
|
}
|
|
|
|
close (STDIN_FILENO);
|
|
close (STDOUT_FILENO);
|
|
close (STDERR_FILENO);
|
|
|
|
return EXIT_SUCCESS;
|
|
}
|