bindresvport.c (7f3dea244c40159a41ab22da77a434d7c5b5e85a) bindresvport.c (42b4f28ebdf07192c1a09a8711cb7c31a09b9381)
1/*
2 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
3 * unrestricted use provided that this legend is included on all tape
4 * media and as a part of the software program in whole or part. Users
5 * may copy or modify Sun RPC without charge, but are not authorized
6 * to license or distribute it to anyone else except as part of a product or
7 * program developed by the user.
8 *

--- 41 unchanged lines hidden (view full) ---

50/*
51 * Bind a socket to a privileged IP port
52 */
53int
54bindresvport(sd, sin)
55 int sd;
56 struct sockaddr_in *sin;
57{
1/*
2 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
3 * unrestricted use provided that this legend is included on all tape
4 * media and as a part of the software program in whole or part. Users
5 * may copy or modify Sun RPC without charge, but are not authorized
6 * to license or distribute it to anyone else except as part of a product or
7 * program developed by the user.
8 *

--- 41 unchanged lines hidden (view full) ---

50/*
51 * Bind a socket to a privileged IP port
52 */
53int
54bindresvport(sd, sin)
55 int sd;
56 struct sockaddr_in *sin;
57{
58 int on, old, error;
59 struct sockaddr_in myaddr;
60 int sinlen = sizeof(struct sockaddr_in);
61
62 if (sin == (struct sockaddr_in *)0) {
63 sin = &myaddr;
64 memset(sin, 0, sinlen);
65 sin->sin_len = sinlen;
66 sin->sin_family = AF_INET;
67 } else if (sin->sin_family != AF_INET) {
68 errno = EPFNOSUPPORT;
69 return (-1);
70 }
71
58 struct sockaddr_in myaddr;
59 int sinlen = sizeof(struct sockaddr_in);
60
61 if (sin == (struct sockaddr_in *)0) {
62 sin = &myaddr;
63 memset(sin, 0, sinlen);
64 sin->sin_len = sinlen;
65 sin->sin_family = AF_INET;
66 } else if (sin->sin_family != AF_INET) {
67 errno = EPFNOSUPPORT;
68 return (-1);
69 }
70
72 if (sin->sin_port == 0) {
71 return (bindresvport2(sd, sin, sinlen));
72}
73
74int
75bindresvport2(sd, sa, addrlen)
76 int sd;
77 struct sockaddr *sa;
78 socklen_t addrlen;
79{
80 int on, old, error, level, optname;
81 u_short port;
82
83 if (sa == NULL) {
84 errno = EINVAL;
85 return (-1);
86 }
87 switch (sa->sa_family) {
88 case AF_INET:
89 port = ntohs(((struct sockaddr_in *)sa)->sin_port);
90 level = IPPROTO_IP;
91 optname = IP_PORTRANGE;
92 on = IP_PORTRANGE_LOW;
93 break;
94#ifdef INET6
95 case AF_INET6:
96 port = ntohs(((struct sockaddr_in6 *)sa)->sin6_port);
97 level = IPPROTO_IPV6;
98 optname = IPV6_PORTRANGE;
99 on = IPV6_PORTRANGE_LOW;
100 break;
101#endif
102 default:
103 errno = EAFNOSUPPORT;
104 return (-1);
105 }
106
107 if (port == 0) {
73 int oldlen = sizeof(old);
108 int oldlen = sizeof(old);
74 error = getsockopt(sd, IPPROTO_IP, IP_PORTRANGE,
75 &old, &oldlen);
109 error = getsockopt(sd, level, optname, &old, &oldlen);
76 if (error < 0)
77 return(error);
78
110 if (error < 0)
111 return(error);
112
79 on = IP_PORTRANGE_LOW;
80 error = setsockopt(sd, IPPROTO_IP, IP_PORTRANGE,
81 &on, sizeof(on));
113 error = setsockopt(sd, level, optname, &on, sizeof(on));
82 if (error < 0)
83 return(error);
84 }
85
114 if (error < 0)
115 return(error);
116 }
117
86 error = bind(sd, (struct sockaddr *)sin, sinlen);
118 error = bind(sd, sa, addrlen);
87
119
88 if (sin->sin_port == 0) {
120 switch (sa->sa_family) {
121 case AF_INET:
122 port = ntohs(((struct sockaddr_in *)sa)->sin_port);
123 break;
124#ifdef INET6
125 case AF_INET6:
126 port = ntohs(((struct sockaddr_in6 *)sa)->sin6_port);
127 break;
128#endif
129 default: /* shoud not match here */
130 errno = EAFNOSUPPORT;
131 return (-1);
132 }
133 if (port == 0) {
89 int saved_errno = errno;
90
91 if (error) {
134 int saved_errno = errno;
135
136 if (error) {
92 if (setsockopt(sd, IPPROTO_IP, IP_PORTRANGE,
137 if (setsockopt(sd, level, optname,
93 &old, sizeof(old)) < 0)
94 errno = saved_errno;
95 return (error);
96 }
97
138 &old, sizeof(old)) < 0)
139 errno = saved_errno;
140 return (error);
141 }
142
98 if (sin != &myaddr) {
99 /* Hmm, what did the kernel assign... */
100 if (getsockname(sd, (struct sockaddr *)sin,
101 &sinlen) < 0)
102 errno = saved_errno;
103 return (error);
104 }
143 /* Hmm, what did the kernel assign... */
144 if (getsockname(sd, (struct sockaddr *)sa, &addrlen) < 0)
145 errno = saved_errno;
146 return (error);
105 }
106 return (error);
107}
147 }
148 return (error);
149}