Handle socket option control request for PCB */
| 415 | |
| 416 | /* Handle socket option control request for PCB */ |
| 417 | static int |
| 418 | ipsec_control_pcbpolicy(struct inpcb *inp, struct sockopt *sopt) |
| 419 | { |
| 420 | void *optdata; |
| 421 | size_t optlen; |
| 422 | int error; |
| 423 | |
| 424 | if (inp->inp_sp == NULL) |
| 425 | return (ENOPROTOOPT); |
| 426 | |
| 427 | /* Limit maximum request size to PAGE_SIZE */ |
| 428 | optlen = sopt->sopt_valsize; |
| 429 | if (optlen < sizeof(struct sadb_x_policy) || optlen > PAGE_SIZE) |
| 430 | return (EINVAL); |
| 431 | |
| 432 | optdata = malloc(optlen, M_TEMP, sopt->sopt_td ? M_WAITOK: M_NOWAIT); |
| 433 | if (optdata == NULL) |
| 434 | return (ENOBUFS); |
| 435 | /* |
| 436 | * We need a hint from the user, what policy is requested - input |
| 437 | * or output? User should specify it in the buffer, even for |
| 438 | * setsockopt(). |
| 439 | */ |
| 440 | error = sooptcopyin(sopt, optdata, optlen, optlen); |
| 441 | if (error == 0) { |
| 442 | if (sopt->sopt_dir == SOPT_SET) |
| 443 | error = ipsec_set_pcbpolicy(inp, |
| 444 | sopt->sopt_td ? sopt->sopt_td->td_ucred: NULL, |
| 445 | optdata, optlen); |
| 446 | else { |
| 447 | error = ipsec_get_pcbpolicy(inp, optdata, &optlen); |
| 448 | if (error == 0) |
| 449 | error = sooptcopyout(sopt, optdata, optlen); |
| 450 | } |
| 451 | } |
| 452 | free(optdata, M_TEMP); |
| 453 | return (error); |
| 454 | } |
| 455 | |
| 456 | #ifdef INET |
| 457 | /* |
no test coverage detected