| #include <errno.h> | |
| #include <comboot.h> | |
| #include <ipxe/in.h> | |
| #include <ipxe/list.h> | |
| #include <ipxe/process.h> | |
| #include <ipxe/resolv.h> | |
| FILE_LICENCE ( GPL2_OR_LATER ); | |
| struct comboot_resolver { | |
| struct interface intf; | |
| int rc; | |
| struct in_addr addr; | |
| }; | |
| static void comboot_resolv_close ( struct comboot_resolver *comboot_resolver, | |
| int rc ) { | |
| comboot_resolver->rc = rc; | |
| intf_shutdown ( &comboot_resolver->intf, rc ); | |
| } | |
| static void comboot_resolv_done ( struct comboot_resolver *comboot_resolver, | |
| struct sockaddr *sa ) { | |
| struct sockaddr_in *sin; | |
| if ( sa->sa_family == AF_INET ) { | |
| sin = ( ( struct sockaddr_in * ) sa ); | |
| comboot_resolver->addr = sin->sin_addr; | |
| } | |
| } | |
| static struct interface_operation comboot_resolv_op[] = { | |
| INTF_OP ( intf_close, struct comboot_resolver *, comboot_resolv_close ), | |
| INTF_OP ( resolv_done, struct comboot_resolver *, comboot_resolv_done ), | |
| }; | |
| static struct interface_descriptor comboot_resolv_desc = | |
| INTF_DESC ( struct comboot_resolver, intf, comboot_resolv_op ); | |
| static struct comboot_resolver comboot_resolver = { | |
| .intf = INTF_INIT ( comboot_resolv_desc ), | |
| }; | |
| int comboot_resolv ( const char *name, struct in_addr *address ) { | |
| int rc; | |
| comboot_resolver.rc = -EINPROGRESS; | |
| comboot_resolver.addr.s_addr = 0; | |
| if ( ( rc = resolv ( &comboot_resolver.intf, name, NULL ) ) != 0 ) | |
| return rc; | |
| while ( comboot_resolver.rc == -EINPROGRESS ) | |
| step(); | |
| if ( ! comboot_resolver.addr.s_addr ) | |
| return -EAFNOSUPPORT; | |
| *address = comboot_resolver.addr; | |
| return comboot_resolver.rc; | |
| } |