Commit | Line | Data |
---|---|---|
e1b631e8 | 1 | /* |
d3faac99 KB |
2 | * Copyright (c) 1992, 1993 |
3 | * The Regents of the University of California. All rights reserved. | |
e1b631e8 JSP |
4 | * All rights reserved. |
5 | * | |
6 | * This code is derived from software donated to Berkeley by | |
7 | * Jan-Simon Pendry. | |
8 | * | |
9 | * %sccs.include.redist.c% | |
10 | * | |
1233d419 | 11 | * @(#)pt_tcp.c 8.3 (Berkeley) %G% |
e1b631e8 JSP |
12 | * |
13 | * $Id: pt_tcp.c,v 1.1 1992/05/25 21:43:09 jsp Exp jsp $ | |
14 | */ | |
15 | ||
16 | #include <stdio.h> | |
17 | #include <unistd.h> | |
18 | #include <stdlib.h> | |
19 | #include <errno.h> | |
225429d9 | 20 | #include <strings.h> |
e1b631e8 | 21 | #include <sys/types.h> |
225429d9 | 22 | #include <sys/param.h> |
e1b631e8 | 23 | #include <sys/syslog.h> |
0be6ec50 JSP |
24 | #include <sys/socket.h> |
25 | #include <netinet/in.h> | |
1233d419 | 26 | #include <arpa/inet.h> |
0be6ec50 | 27 | #include <netdb.h> |
e1b631e8 JSP |
28 | |
29 | #include "portald.h" | |
30 | ||
225429d9 JSP |
31 | /* |
32 | * Key will be tcp/host/port[/"priv"] | |
33 | * Create a TCP socket connected to the | |
34 | * requested host and port. | |
35 | * Some trailing suffix values have special meanings. | |
36 | * An unrecognised suffix is an error. | |
37 | */ | |
0be6ec50 | 38 | int portal_tcp(pcr, key, v, kso, fdp) |
e1b631e8 JSP |
39 | struct portal_cred *pcr; |
40 | char *key; | |
41 | char **v; | |
0be6ec50 | 42 | int kso; |
e1b631e8 JSP |
43 | int *fdp; |
44 | { | |
225429d9 JSP |
45 | char host[MAXHOSTNAMELEN]; |
46 | char port[MAXHOSTNAMELEN]; | |
47 | char *p = key + (v[1] ? strlen(v[1]) : 0); | |
48 | char *q; | |
0be6ec50 JSP |
49 | struct hostent *hp; |
50 | struct servent *sp; | |
51 | struct in_addr **ipp; | |
52 | struct in_addr *ip[2]; | |
53 | struct in_addr ina; | |
54 | int s_port; | |
7736a2e4 | 55 | int priv = 0; |
0be6ec50 | 56 | struct sockaddr_in sain; |
225429d9 JSP |
57 | |
58 | q = strchr(p, '/'); | |
59 | if (q == 0 || q - p >= sizeof(host)) | |
60 | return (EINVAL); | |
61 | *q = '\0'; | |
62 | strcpy(host, p); | |
7736a2e4 | 63 | p = q + 1; |
225429d9 JSP |
64 | |
65 | q = strchr(p, '/'); | |
7736a2e4 JSP |
66 | if (q) |
67 | *q = '\0'; | |
68 | if (strlen(p) >= sizeof(port)) | |
225429d9 | 69 | return (EINVAL); |
225429d9 | 70 | strcpy(port, p); |
7736a2e4 JSP |
71 | if (q) { |
72 | p = q + 1; | |
73 | if (strcmp(p, "priv") == 0) { | |
74 | if (pcr->pcr_uid == 0) | |
75 | priv = 1; | |
76 | else | |
77 | return (EPERM); | |
78 | } else { | |
79 | return (EINVAL); | |
80 | } | |
81 | } | |
225429d9 | 82 | |
0be6ec50 JSP |
83 | hp = gethostbyname(host); |
84 | if (hp != 0) { | |
85 | ipp = (struct in_addr **) hp->h_addr_list; | |
86 | } else { | |
87 | ina.s_addr = inet_addr(host); | |
88 | if (ina.s_addr == INADDR_NONE) | |
89 | return (EINVAL); | |
90 | ip[0] = &ina; | |
91 | ip[1] = 0; | |
92 | ipp = ip; | |
93 | } | |
94 | ||
95 | sp = getservbyname(port, "tcp"); | |
96 | if (sp != 0) | |
97 | s_port = sp->s_port; | |
98 | else { | |
99 | s_port = atoi(port); | |
100 | if (s_port == 0) | |
101 | return (EINVAL); | |
102 | } | |
103 | ||
104 | bzero(&sain, sizeof(sain)); | |
105 | sain.sin_len = sizeof(sain); | |
106 | sain.sin_family = AF_INET; | |
107 | sain.sin_port = s_port; | |
108 | ||
109 | while (ipp[0]) { | |
110 | int so; | |
111 | ||
7736a2e4 JSP |
112 | if (priv) |
113 | so = rresvport((int *) 0); | |
114 | else | |
115 | so = socket(AF_INET, SOCK_STREAM, 0); | |
0be6ec50 JSP |
116 | if (so < 0) { |
117 | syslog(LOG_ERR, "socket: %m"); | |
118 | return (errno); | |
119 | } | |
120 | ||
121 | sain.sin_addr = *ipp[0]; | |
122 | if (connect(so, (struct sockaddr *) &sain, sizeof(sain)) == 0) { | |
123 | *fdp = so; | |
124 | return (0); | |
125 | } | |
126 | (void) close(so); | |
127 | ||
128 | ipp++; | |
129 | } | |
130 | ||
131 | return (errno); | |
e1b631e8 | 132 | } |