* Hardware specific interface ioctls. */
| 2459 | * Hardware specific interface ioctls. |
| 2460 | */ |
| 2461 | int |
| 2462 | ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td) |
| 2463 | { |
| 2464 | struct ifreq *ifr; |
| 2465 | int error = 0, do_ifup = 0; |
| 2466 | int new_flags, temp_flags; |
| 2467 | size_t namelen, onamelen; |
| 2468 | size_t descrlen; |
| 2469 | char *descrbuf, *odescrbuf; |
| 2470 | char new_name[IFNAMSIZ]; |
| 2471 | struct ifaddr *ifa; |
| 2472 | struct sockaddr_dl *sdl; |
| 2473 | |
| 2474 | ifr = (struct ifreq *)data; |
| 2475 | switch (cmd) { |
| 2476 | case SIOCGIFINDEX: |
| 2477 | ifr->ifr_index = ifp->if_index; |
| 2478 | break; |
| 2479 | |
| 2480 | case SIOCGIFFLAGS: |
| 2481 | temp_flags = ifp->if_flags | ifp->if_drv_flags; |
| 2482 | ifr->ifr_flags = temp_flags & 0xffff; |
| 2483 | ifr->ifr_flagshigh = temp_flags >> 16; |
| 2484 | break; |
| 2485 | |
| 2486 | case SIOCGIFCAP: |
| 2487 | ifr->ifr_reqcap = ifp->if_capabilities; |
| 2488 | ifr->ifr_curcap = ifp->if_capenable; |
| 2489 | break; |
| 2490 | |
| 2491 | case SIOCGIFDATA: |
| 2492 | { |
| 2493 | struct if_data ifd; |
| 2494 | |
| 2495 | /* Ensure uninitialised padding is not leaked. */ |
| 2496 | memset(&ifd, 0, sizeof(ifd)); |
| 2497 | |
| 2498 | if_data_copy(ifp, &ifd); |
| 2499 | error = copyout(&ifd, ifr_data_get_ptr(ifr), sizeof(ifd)); |
| 2500 | break; |
| 2501 | } |
| 2502 | |
| 2503 | #ifdef MAC |
| 2504 | case SIOCGIFMAC: |
| 2505 | error = mac_ifnet_ioctl_get(td->td_ucred, ifr, ifp); |
| 2506 | break; |
| 2507 | #endif |
| 2508 | |
| 2509 | case SIOCGIFMETRIC: |
| 2510 | ifr->ifr_metric = ifp->if_metric; |
| 2511 | break; |
| 2512 | |
| 2513 | case SIOCGIFMTU: |
| 2514 | ifr->ifr_mtu = ifp->if_mtu; |
| 2515 | break; |
| 2516 | |
| 2517 | case SIOCGIFPHYS: |
| 2518 | /* XXXGL: did this ever worked? */ |
no test coverage detected