| 1095 | #endif /* INET */ |
| 1096 | |
| 1097 | static int |
| 1098 | rip_pcblist(SYSCTL_HANDLER_ARGS) |
| 1099 | { |
| 1100 | struct xinpgen xig; |
| 1101 | struct epoch_tracker et; |
| 1102 | struct inpcb *inp; |
| 1103 | int error; |
| 1104 | |
| 1105 | if (req->newptr != 0) |
| 1106 | return (EPERM); |
| 1107 | |
| 1108 | if (req->oldptr == 0) { |
| 1109 | int n; |
| 1110 | |
| 1111 | n = V_ripcbinfo.ipi_count; |
| 1112 | n += imax(n / 8, 10); |
| 1113 | req->oldidx = 2 * (sizeof xig) + n * sizeof(struct xinpcb); |
| 1114 | return (0); |
| 1115 | } |
| 1116 | |
| 1117 | if ((error = sysctl_wire_old_buffer(req, 0)) != 0) |
| 1118 | return (error); |
| 1119 | |
| 1120 | bzero(&xig, sizeof(xig)); |
| 1121 | xig.xig_len = sizeof xig; |
| 1122 | xig.xig_count = V_ripcbinfo.ipi_count; |
| 1123 | xig.xig_gen = V_ripcbinfo.ipi_gencnt; |
| 1124 | xig.xig_sogen = so_gencnt; |
| 1125 | error = SYSCTL_OUT(req, &xig, sizeof xig); |
| 1126 | if (error) |
| 1127 | return (error); |
| 1128 | |
| 1129 | NET_EPOCH_ENTER(et); |
| 1130 | for (inp = CK_LIST_FIRST(V_ripcbinfo.ipi_listhead); |
| 1131 | inp != NULL; |
| 1132 | inp = CK_LIST_NEXT(inp, inp_list)) { |
| 1133 | INP_RLOCK(inp); |
| 1134 | if (inp->inp_gencnt <= xig.xig_gen && |
| 1135 | cr_canseeinpcb(req->td->td_ucred, inp) == 0) { |
| 1136 | struct xinpcb xi; |
| 1137 | |
| 1138 | in_pcbtoxinpcb(inp, &xi); |
| 1139 | INP_RUNLOCK(inp); |
| 1140 | error = SYSCTL_OUT(req, &xi, sizeof xi); |
| 1141 | if (error) |
| 1142 | break; |
| 1143 | } else |
| 1144 | INP_RUNLOCK(inp); |
| 1145 | } |
| 1146 | NET_EPOCH_EXIT(et); |
| 1147 | |
| 1148 | if (!error) { |
| 1149 | /* |
| 1150 | * Give the user an updated idea of our state. If the |
| 1151 | * generation differs from what we told her before, she knows |
| 1152 | * that something happened while we were processing this |
| 1153 | * request, and it might be necessary to retry. |
| 1154 | */ |
nothing calls this directly
no test coverage detected