4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
28 * This file delivers /usr/lib/servinfo which provides description for
29 * IANA and running RPC services. Given a IANA name or RPC program name
30 * or number, the program uses getservbyname(3SOCKET) and rpcbind(3NSL)
31 * to obtain port and proto information for the specified service.
37 #include <netconfig.h>
40 #include <rpc/rpcent.h>
41 #include <sys/types.h>
42 #include <netinet/in.h>
50 #define TEXT_DOMAIN "SUNW_OST_OSCMD"
51 #endif /* TEXT_DOMAIN */
62 #define NETID_LEN 12 /* length for a netid or 2^16 port value */
67 (void) fprintf(stderr
, gettext("Usage: %s [-R] [-Pp] [-tu[6]] "
68 "-s service_name\n"), arg0
);
72 uaddr2port(char *addr
)
77 if ((dot
= strrchr(addr
, '.')) == 0) {
86 * If the first dot hasn't been seen, it's a
87 * malformed universal address.
94 port
= strtol(p
+ 1, &dot
, 10) << 8;
95 port
= port
| strtol(dot
+ 1, (char **)NULL
, 10);
102 svc_getrpcinfo(char *sname
, char *sproto
, int options
)
104 struct netconfig
*nconf
;
105 struct rpcblist
*blist
;
108 struct rpcent rentry
;
110 char line
[LINE_MAX
] = "";
111 int line_len
= LINE_MAX
- 1;
114 prognum
= atoi(sname
);
116 rpc
= (struct rpcent
*)getrpcbynumber(prognum
);
118 rpc
= (struct rpcent
*)getrpcbyname(sname
);
121 * If an entry doesn't exist, it could be a running program
122 * without a registered RPC entry.
126 (void) fprintf(stderr
,
127 gettext("Can't get rpc entry\n"));
132 rpc
->r_number
= prognum
;
136 if (setnetconfig() == NULL
) {
137 (void) fprintf(stderr
, gettext("setnetconfig failed\n"));
141 if ((nconf
= getnetconfigent(TCP
)) == NULL
) {
142 (void) fprintf(stderr
, gettext("getnetconfig failed\n"));
146 if ((blist
= (struct rpcblist
*)rpcb_getmaps(nconf
, "localhost"))
148 (void) fprintf(stderr
,
149 gettext("Failed: rpcb_getmaps failed\n"));
153 for (; blist
!= NULL
; blist
= blist
->rpcb_next
) {
154 if (blist
->rpcb_map
.r_prog
!= rpc
->r_number
)
158 if (strcmp(blist
->rpcb_map
.r_netid
, sproto
) != 0)
161 if (strcmp(blist
->rpcb_map
.r_netid
, UDP
) &&
162 strcmp(blist
->rpcb_map
.r_netid
, UDP6
) &&
163 strcmp(blist
->rpcb_map
.r_netid
, TCP
) &&
164 strcmp(blist
->rpcb_map
.r_netid
, TCP6
))
167 rpc_port
= uaddr2port(blist
->rpcb_map
.r_addr
);
169 if (options
& DEFAULT
) {
170 (void) printf("Program %ld\n", blist
->rpcb_map
.r_prog
);
171 (void) printf("Protocol %s\n", blist
->rpcb_map
.r_netid
);
172 (void) printf("Port %ld\n", rpc_port
);
173 (void) printf("Version %ld\n", blist
->rpcb_map
.r_vers
);
174 (void) printf("Name %s\n", rpc
->r_name
);
176 } else if (options
& PROTO
) {
177 if (strstr(line
, blist
->rpcb_map
.r_netid
))
180 (void) snprintf(buf
, sizeof (buf
), "%5s ",
181 blist
->rpcb_map
.r_netid
);
183 if (strlen(buf
) > line_len
)
186 line_len
= line_len
- strlen(buf
);
187 (void) strlcat(line
, buf
, sizeof (line
));
189 (void) snprintf(buf
, sizeof (buf
), "%-7ld ", rpc_port
);
191 if (strstr(line
, buf
) || strlen(buf
) > line_len
)
194 line_len
= line_len
- strlen(buf
);
195 (void) strlcat(line
, buf
, sizeof (line
));
200 * Print the concatenated output if options is PROTO or PORT.
202 if (options
& (PROTO
| PORT
))
209 main(int argc
, char *argv
[])
211 struct servent
*service
;
214 int options
= DEFAULT
;
215 int c
, isrpc
= 0, v6_flag
= 0;
217 (void) setlocale(LC_ALL
, "");
218 (void) textdomain(TEXT_DOMAIN
);
222 while ((c
= getopt(argc
, argv
, "s:PplRtu6?")) != -1) {
256 * Specified service is an RPC service.
259 if (sproto
&& v6_flag
) {
260 if (strcmp(sproto
, TCP
) == 0)
262 if (strcmp(sproto
, UDP
) == 0)
266 return (svc_getrpcinfo(sname
, sproto
, options
));
269 if ((service
= getservbyname(sname
, sproto
)) == NULL
) {
270 (void) fprintf(stderr
, gettext(
271 "Failed to get information for %s\n"), sname
);
275 if (options
& DEFAULT
) {
276 (void) printf("Name %s\n", service
->s_name
);
277 (void) printf("Protocol %s\n", service
->s_proto
);
278 (void) printf("Port %d\n", htons(service
->s_port
));
279 } else if (options
& PROTO
)
280 (void) printf("%s\n", service
->s_proto
);
282 (void) printf("%d\n", htons(service
->s_port
));