1
/* Copyright (C) 2002 Free Software Foundation, Inc.
2
This file is part of the GNU C Library.
4
The GNU C Library is free software; you can redistribute it and/or
5
modify it under the terms of the GNU Lesser General Public
6
License as published by the Free Software Foundation; either
7
version 2.1 of the License, or (at your option) any later version.
9
The GNU C Library 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 GNU
12
Lesser General Public License for more details.
14
You should have received a copy of the GNU Lesser General Public
15
License along with the GNU C Library; if not, write to the Free
16
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
24
#include <sys/socket.h>
33
# define __socket(d, t, p) socket ((d), (t), (p))
34
# define __close(f) close ((f))
38
svc_socket (u_long number, int type, int protocol, int reuse)
40
struct sockaddr_in addr;
41
socklen_t len = sizeof (struct sockaddr_in);
42
char rpcdata [1024], servdata [1024];
43
struct rpcent rpcbuf, *rpcp;
44
struct servent servbuf, *servp;
46
const char *proto = protocol == IPPROTO_TCP ? "tcp" : "udp";
48
if ((sock = __socket (AF_INET, type, protocol)) < 0)
50
perror (_("svc_socket: socket creation problem"));
57
ret = setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, &ret,
61
perror (_("svc_socket: socket reuse problem"));
66
__bzero ((char *) &addr, sizeof (addr));
67
addr.sin_family = AF_INET;
69
ret = getrpcbynumber_r (number, &rpcbuf, rpcdata, sizeof rpcdata,
71
if (ret == 0 && rpcp != NULL)
74
ret = getservbyname_r (rpcp->r_name, proto, &servbuf, servdata,
75
sizeof servdata, &servp);
76
if ((ret != 0 || servp == NULL) && rpcp->r_aliases)
80
/* Then we try aliases. */
81
for (a = (const char **) rpcp->r_aliases; *a != NULL; a++)
83
ret = getservbyname_r (*a, proto, &servbuf, servdata,
84
sizeof servdata, &servp);
85
if (ret == 0 && servp != NULL)
91
if (ret == 0 && servp != NULL)
93
addr.sin_port = servp->s_port;
94
if (bind (sock, (struct sockaddr *) &addr, len) < 0)
96
perror (_("svc_socket: bind problem"));
97
(void) __close (sock);
103
if (bindresvport (sock, &addr))
106
if (bind (sock, (struct sockaddr *) &addr, len) < 0)
108
perror (_("svc_socket: bind problem"));
109
(void) __close (sock);
119
* Create and bind a TCP socket based on program number
122
svctcp_socket (u_long number, int reuse)
124
return svc_socket (number, SOCK_STREAM, IPPROTO_TCP, reuse);
128
* Create and bind a UDP socket based on program number
131
svcudp_socket (u_long number, int reuse)
133
return svc_socket (number, SOCK_DGRAM, IPPROTO_UDP, reuse);
138
check (u_long number, u_short port, int protocol, int reuse)
142
struct sockaddr_in addr;
143
socklen_t len = sizeof (struct sockaddr_in);
145
if (protocol == IPPROTO_TCP)
146
socket = svctcp_socket (number, reuse);
148
socket = svcudp_socket (number, reuse);
153
result = getsockname (socket, (struct sockaddr *) &addr, &len);
156
if (port != 0 && ntohs (addr.sin_port) != port)
157
printf ("Program: %ld, expect port: %d, got: %d\n",
158
number, port, ntohs (addr.sin_port));
160
printf ("Program: %ld, port: %d\n",
161
number, ntohs (addr.sin_port));
173
result += check (100001, 0, IPPROTO_TCP, 0);
174
result += check (100001, 0, IPPROTO_UDP, 0);
175
result += check (100003, 2049, IPPROTO_TCP, 1);
176
result += check (100003, 2049, IPPROTO_UDP, 1);