File: getpeername.c

package info (click to toggle)
tcputils 0.6.2%2Bgit20120127.c28952d-0.1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 264 kB
  • sloc: ansic: 1,277; sh: 348; makefile: 102
file content (127 lines) | stat: -rw-r--r-- 2,419 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>


extern	int	 getopt(int, char *const*, const char *);
extern	int	 optind;
extern	char	*optarg;


char	* progname		= "getpeername";

int	  numeric_addresses	= 0;
char	* protocol		= NULL;
int	  sockno		= 0;



void
usage(void)
{
    fprintf(stderr, "Usage: %s [-n] [-p protocol]\n", progname);
    exit(1);
}


void
fatal(char	* msg)
{
    fprintf(stderr, "%s: %s: %s\n", progname, msg, strerror(errno));
    exit(1);
}


int
main(int argc,
     char **argv)
{
    int			  option;
    struct sockaddr_in	  peer;
    int			  peersize	= sizeof peer;
    char		* hostname;
    char		* portname;
    char		  servbuf[64];

    progname = argv[0];

    while ((option = getopt(argc, argv, "np:")) != EOF)
    {
	switch ((char)option)
	{
	case 'n':
	    numeric_addresses = 1;
	    break;
	case 'p':
	    protocol = optarg;
	    break;
	default:
	    usage();
	    /* NOTREACHED */
	}
    }

    if (argc - optind > 0)
	usage();

    if (getpeername(sockno, (struct sockaddr*)&peer, &peersize) < 0)
	fatal("can't get peer name");
    if (peer.sin_family != AF_INET)
	fatal("socket is not an IP socket");

    /* Find the type of the socket.  Assumes that an INET stream socket
     * is TCP and an INET datagram socket is UDP.  Can't handle AF_UNIX
     * or any other adress families.
     */
    if (protocol == NULL)
    {
	int socktype;
	int socktypelen = sizeof socktype;

	if (getsockopt(sockno, SOL_SOCKET, SO_TYPE,
		       (char*)&socktype, &socktypelen) < 0)
	    fatal("can't get socket type");

	switch (socktype)
	{
	case SOCK_STREAM:
	    protocol = "tcp";
	    break;
	case SOCK_DGRAM:
	    protocol = "udp";
	    break;
	default:
	    fatal("unknown socket type");
	    /* NOTREACHED */
	}
    }

    hostname = inet_ntoa(peer.sin_addr);
    sprintf(servbuf, "%u", ntohs(peer.sin_port));
    portname = servbuf;

    if (!numeric_addresses) 
    {
	struct hostent *host;
	struct servent *service;

	host = gethostbyaddr((char*)&peer.sin_addr.s_addr,
			     sizeof peer.sin_addr.s_addr, AF_INET);
	if (host != NULL)
	    hostname = host->h_name;
	service = getservbyport(peer.sin_port, protocol);
	if (service != NULL)
	    portname = service->s_name;
    }

    printf("%s %s\n", hostname, portname);

    return 0;
}