* Process an ioctl request. */
| 1279 | * Process an ioctl request. |
| 1280 | */ |
| 1281 | static int |
| 1282 | tunifioctl(struct ifnet *ifp, u_long cmd, caddr_t data) |
| 1283 | { |
| 1284 | struct ifreq *ifr = (struct ifreq *)data; |
| 1285 | struct tuntap_softc *tp; |
| 1286 | struct ifstat *ifs; |
| 1287 | struct ifmediareq *ifmr; |
| 1288 | int dummy, error = 0; |
| 1289 | bool l2tun; |
| 1290 | |
| 1291 | ifmr = NULL; |
| 1292 | sx_xlock(&tun_ioctl_sx); |
| 1293 | tp = ifp->if_softc; |
| 1294 | if (tp == NULL) { |
| 1295 | error = ENXIO; |
| 1296 | goto bad; |
| 1297 | } |
| 1298 | l2tun = (tp->tun_flags & TUN_L2) != 0; |
| 1299 | switch(cmd) { |
| 1300 | case SIOCGIFSTATUS: |
| 1301 | ifs = (struct ifstat *)data; |
| 1302 | TUN_LOCK(tp); |
| 1303 | if (tp->tun_pid) |
| 1304 | snprintf(ifs->ascii, sizeof(ifs->ascii), |
| 1305 | "\tOpened by PID %d\n", tp->tun_pid); |
| 1306 | else |
| 1307 | ifs->ascii[0] = '\0'; |
| 1308 | TUN_UNLOCK(tp); |
| 1309 | break; |
| 1310 | case SIOCSIFADDR: |
| 1311 | if (l2tun) |
| 1312 | error = ether_ioctl(ifp, cmd, data); |
| 1313 | else |
| 1314 | tuninit(ifp); |
| 1315 | if (error == 0) |
| 1316 | TUNDEBUG(ifp, "address set\n"); |
| 1317 | break; |
| 1318 | case SIOCSIFMTU: |
| 1319 | ifp->if_mtu = ifr->ifr_mtu; |
| 1320 | TUNDEBUG(ifp, "mtu set\n"); |
| 1321 | break; |
| 1322 | case SIOCSIFFLAGS: |
| 1323 | case SIOCADDMULTI: |
| 1324 | case SIOCDELMULTI: |
| 1325 | break; |
| 1326 | case SIOCGIFMEDIA: |
| 1327 | if (!l2tun) { |
| 1328 | error = EINVAL; |
| 1329 | break; |
| 1330 | } |
| 1331 | |
| 1332 | ifmr = (struct ifmediareq *)data; |
| 1333 | dummy = ifmr->ifm_count; |
| 1334 | ifmr->ifm_count = 1; |
| 1335 | ifmr->ifm_status = IFM_AVALID; |
| 1336 | ifmr->ifm_active = IFM_ETHER; |
| 1337 | if (tp->tun_flags & TUN_OPEN) |
| 1338 | ifmr->ifm_status |= IFM_ACTIVE; |
nothing calls this directly
no test coverage detected