On Tuesday 10 June 2008, Sepherosa Ziehau wrote:
Yes, I know. I'm in the middle of updating the callees. This is how I'm doing
it:
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c
index 9278ffa..549352f 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -1418,8 +1418,7 @@ ip_ctloutput(struct socket *so, struct sockopt *sopt)
break;
}
m->m_len = sopt->sopt_valsize;
- error = sooptcopyin(sopt, mtod(m, char *), m->m_len,
- m->m_len);
+ bcopy(sopt->sopt_val, mtod(m, void *), m->m_len);
return (ip_pcbopts(sopt->sopt_name, &inp->inp_options,
m));
@@ -1434,10 +1433,11 @@ ip_ctloutput(struct socket *so, struct sockopt *sopt)
case IP_RECVIF:
case IP_RECVTTL:
case IP_FAITH:
- error = sooptcopyin(sopt, &optval, sizeof optval,
- sizeof optval);
- if (error)
+ if (sopt->sopt_valsize != sizeof optval) {
+ error = EINVAL;
break;
+ }
+ optval = *(int *)sopt->sopt_val;
switch (sopt->sopt_name) {
case IP_TOS:
@@ -1826,6 +1826,13 @@ ip_setmoptions(struct sockopt *sopt, struct ip_moptions **imop)
imo->imo_num_memberships = 0;
}
+#define getval(var) \
+ if (sopt->sopt_valsize != sizeof var) { \
+ error = EINVAL; \
+ break; \
+ } \
+ bcopy(sopt->sopt_val, &var, sizeof var) \
+
switch (sopt->sopt_name) {
/* store an index number for the vif you wanna use in the send */
case IP_MULTICAST_VIF:
@@ -1833,9 +1840,7 @@ ip_setmoptions(struct sockopt *sopt, struct ip_moptions **imop)
error = EOPNOTSUPP;
break;
}
- error = sooptcopyin(sopt, &i, sizeof i, sizeof i);
- if (error)
- break;
+ getval(i);
if (!legal_vif_num(i) && (i != -1)) {
error = EINVAL;
break;
@@ -1847,9 +1852,7 @@ ip_setmoptions(struct sockopt *sopt, struct ip_moptions **imop)
/*
* Select the interface for outgoing multicast packets.
*/
- error = sooptcopyin(sopt, &addr, sizeof addr, sizeof addr);
- if (error)
- break;
+ getval(addr);
/*
* INADDR_ANY is used to remove a previous selection.
* When no interface is selected, a default one is
@@ -1888,15 +1891,11 @@ ip_setmoptions(struct sockopt *sopt, struct ip_moptions **imop)
*/
if (sopt->sopt_valsize == 1) {
u_char ttl;
- error = sooptcopyin(sopt, &ttl, 1, 1);
- if (error)
- break;
+ getval(ttl);
imo->imo_multicast_ttl = ttl;
} else {
u_int ttl;
- error = sooptcopyin(sopt, &ttl, sizeof ttl, sizeof ttl);
- if (error)
- break;
+ getval(ttl);
if (ttl > 255)
error = EINVAL;
else
@@ -1914,17 +1913,12 @@ ip_setmoptions(struct sockopt *sopt, struct ip_moptions **imop)
if (sopt->sopt_valsize == 1) {
u_char loop;
- error = sooptcopyin(sopt, &loop, 1, 1);
- if (error)
- break;
+ getval(loop);
imo->imo_multicast_loop = !!loop;
} else {
u_int loop;
- error = sooptcopyin(sopt, &loop, sizeof loop,
- sizeof loop);
- if (error)
- break;
+ getval(loop);
imo->imo_multicast_loop = !!loop;
}
break;
@@ -1934,9 +1928,7 @@ ip_setmoptions(struct sockopt *sopt, struct ip_moptions **imop)
* Add a multicast group membership.
* Group must be a valid IP multicast address.
*/
- error = sooptcopyin(sopt, &mreq, sizeof mreq, sizeof mreq);
- if (error)
- break;
+ getval(mreq);
if (!IN_MULTICAST(ntohl(mreq.imr_multiaddr.s_addr))) {
error = EINVAL;
@@ -2015,10 +2007,8 @@ ip_setmoptions(struct sockopt *sopt, struct ip_moptions **imop)
* Drop a multicast group membership.
* Group must be a valid IP multicast address.
*/
- error = sooptcopyin(sopt, &mreq, sizeof mreq, sizeof mreq);
- if (error)
- break;
-
+ getval(mreq);
+#undef getval
if (!IN_MULTICAST(ntohl(mreq.imr_multiaddr.s_addr))) {
error = EINVAL;
break;
diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c
index 4434133..4cedd42 100644
--- a/sys/netinet/tcp_usrreq.c
+++ b/sys/netinet/tcp_usrreq.c
@@ -1156,14 +1156,14 @@ tcp_ctloutput(struct socket *so, struct sockopt *sopt)
switch (sopt->sopt_dir) {
case SOPT_SET:
+ if (sopt->sopt_valsize != sizeof optval) {
+ error = EINVAL;
+ break;
+ }
+ optval = *(int *)sopt->sopt_valsize;
switch (sopt->sopt_name) {
case TCP_NODELAY:
case TCP_NOOPT:
- error = sooptcopyin(sopt, &optval, sizeof optval,
- sizeof optval);
- if (error)
- break;
-
switch (sopt->sopt_name) {
case TCP_NODELAY:
opt = TF_NODELAY;
@@ -1183,11 +1183,6 @@ tcp_ctloutput(struct socket *so, struct sockopt *sopt)
break;
case TCP_NOPUSH:
- error = sooptcopyin(sopt, &optval, sizeof optval,
- sizeof optval);
- if (error)
- break;
-
if (optval)
tp->t_flags |= TF_NOPUSH;
else {
@@ -1197,11 +1192,6 @@ tcp_ctloutput(struct socket *so, struct sockopt *sopt)
break;
case TCP_MAXSEG:
- error = sooptcopyin(sopt, &optval, sizeof optval,
- sizeof optval);
- if (error)
- break;
-
if (optval > 0 && optval <= tp->t_maxseg)
tp->t_maxseg = optval;
else
@@ -1232,8 +1222,11 @@ tcp_ctloutput(struct socket *so, struct sockopt *sopt)
error = ENOPROTOOPT;
break;
}
- if (error == 0)
- error = sooptcopyout(sopt, &optval, sizeof optval);
+ if (error == 0) {
+ sopt->sopt_valsize = min(sizeof optval,
+ sopt->sopt_valsize);
+ bcopy(&optval, sopt->sopt_val, sopt->sopt_valsize);
+ }
break;
}
crit_exit();
Does that look OK to you?
Thanks,
Aggelos