iPXE
nslookup.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012 Patrick Plenefisch <phplenefisch@wpi.edu>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  */
19 
20 FILE_LICENCE ( GPL2_OR_LATER );
21 FILE_SECBOOT ( PERMITTED );
22 
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include <errno.h>
27 #include <ipxe/resolv.h>
28 #include <ipxe/tcpip.h>
29 #include <ipxe/monojob.h>
30 #include <ipxe/settings.h>
31 #include <usr/nslookup.h>
32 
33 /** @file
34  *
35  * Standalone name resolution
36  *
37  */
38 
39 /** A name resolution request */
40 struct nslookup {
41  /** Reference count for this object */
42  struct refcnt refcnt;
43 
44  /** Job control interface */
45  struct interface job;
46  /** Data transfer interface */
48 
49  /** Setting name */
50  char *setting_name;
51 };
52 
53 /**
54  * Terminate name resolution
55  *
56  * @v nslookup Name resolution request
57  * @v rc Reason for termination
58  */
59 static void nslookup_close ( struct nslookup *nslookup, int rc ) {
60 
61  /* Shut down interfaces */
64 }
65 
66 /**
67  * Handle resolved name
68  *
69  * @v nslookup Name resolution request
70  * @v sa Completed socket address
71  */
72 static void nslookup_resolv_done ( struct nslookup *nslookup,
73  struct sockaddr *sa ) {
74  struct sockaddr_in *sin;
75  struct sockaddr_in6 *sin6;
76  const struct setting_type *default_type;
77  struct settings *settings;
78  struct setting setting;
79  void *data;
80  size_t len;
81  int rc;
82 
83  /* Extract address */
84  switch ( sa->sa_family ) {
85  case AF_INET:
86  sin = ( ( struct sockaddr_in * ) sa );
87  data = &sin->sin_addr;
88  len = sizeof ( sin->sin_addr );
89  default_type = &setting_type_ipv4;
90  break;
91  case AF_INET6:
92  sin6 = ( ( struct sockaddr_in6 * ) sa );
93  data = &sin6->sin6_addr;
94  len = sizeof ( sin6->sin6_addr );
95  default_type = &setting_type_ipv6;
96  break;
97  default:
98  rc = -ENOTSUP;
99  goto err;
100  }
101 
102  /* Parse specified setting name */
105  &setting ) ) != 0 )
106  goto err;
107 
108  /* Apply default type if necessary */
109  if ( ! setting.type )
110  setting.type = default_type;
111 
112  /* Store in specified setting */
113  if ( ( rc = store_setting ( settings, &setting, data, len ) ) != 0 )
114  goto err;
115 
116  err:
117  /* Terminate name resolution */
119 }
120 
121 /** Name resolution resolver interface operations */
124  INTF_OP ( intf_close, struct nslookup *, nslookup_close ),
125 };
126 
127 /** Name resolution resolver interface descriptor */
131 
132 /** Name resolution job control interface operations */
134  INTF_OP ( intf_close, struct nslookup *, nslookup_close ),
135 };
136 
137 /** Name resolution job control interface descriptor */
139  INTF_DESC_PASSTHRU ( struct nslookup, job,
141 
142 /**
143  * Initiate standalone name resolution
144  *
145  * @v job Parent interface
146  * @v name Name to resolve
147  * @v setting_name Setting name
148  * @ret rc Return status code
149  */
150 static int resolv_setting ( struct interface *job, const char *name,
151  const char *setting_name ) {
152  struct nslookup *nslookup;
153  struct sockaddr sa;
154  char *setting_name_copy;
155  int rc;
156 
157  /* Allocate and initialise structure */
158  nslookup = zalloc ( sizeof ( *nslookup ) + strlen ( setting_name )
159  + 1 /* NUL */ );
160  if ( ! nslookup )
161  return -ENOMEM;
162  ref_init ( &nslookup->refcnt, NULL );
165  &nslookup->refcnt );
166  setting_name_copy = ( ( void * ) ( nslookup + 1 ) );
167  strcpy ( setting_name_copy, setting_name );
168  nslookup->setting_name = setting_name_copy;
169 
170  /* Start name resolution */
171  memset ( &sa, 0, sizeof ( sa ) );
172  if ( ( rc = resolv ( &nslookup->resolver, name, &sa ) ) != 0 )
173  goto err_resolv;
174 
175  /* Attach parent interface, mortalise self, and return */
176  intf_plug_plug ( &nslookup->job, job );
177  ref_put ( &nslookup->refcnt );
178  return 0;
179 
180  err_resolv:
181  ref_put ( &nslookup->refcnt );
182  return rc;
183 }
184 
185 /**
186  * Perform (blocking) standalone name resolution
187  *
188  * @v name Name to resolve
189  * @v setting_name Setting name
190  * @ret rc Return status code
191  */
192 int nslookup ( const char *name, const char *setting_name ) {
193  int rc;
194 
195  /* Perform name resolution */
196  if ( ( rc = resolv_setting ( &monojob, name, setting_name ) ) == 0 )
197  rc = monojob_wait ( NULL, 0 );
198  if ( rc != 0 ) {
199  printf ( "Could not resolve %s: %s\n", name, strerror ( rc ) );
200  return rc;
201  }
202 
203  return 0;
204 }
static void nslookup_close(struct nslookup *nslookup, int rc)
Terminate name resolution.
Definition: nslookup.c:59
An object interface operation.
Definition: interface.h:18
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
const char * name
Definition: ath9k_hw.c:1986
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:250
void intf_shutdown(struct interface *intf, int rc)
Shut down an object interface.
Definition: interface.c:279
#define AF_INET6
IPv6 Internet addresses.
Definition: socket.h:65
int printf(const char *fmt,...)
Write a formatted string to the console.
Definition: vsprintf.c:465
int monojob_wait(const char *string, unsigned long timeout)
Wait for single foreground job to complete.
Definition: monojob.c:82
void resolv_done(struct interface *intf, struct sockaddr *sa)
Name resolved.
Definition: resolv.c:56
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:65
Error codes.
Standalone name resolution.
static struct interface_descriptor nslookup_resolver_desc
Name resolution resolver interface descriptor.
Definition: nslookup.c:128
struct refcnt refcnt
Reference count for this object.
Definition: nslookup.c:42
Name resolution.
sa_family_t sa_family
Socket address family.
Definition: socket.h:102
struct interface job
Job control interface.
Definition: nslookup.c:45
struct sockaddr_in6 sin6
Definition: syslog.c:60
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
Definition: interface.c:108
int store_setting(struct settings *settings, const struct setting *setting, const void *data, size_t len)
Store value of setting.
Definition: settings.c:616
IPv4 socket address.
Definition: in.h:85
char * setting_name
Setting name.
Definition: nslookup.c:50
#define ENOTSUP
Operation not supported.
Definition: errno.h:590
A reference counter.
Definition: refcnt.h:27
static int resolv_setting(struct interface *job, const char *name, const char *setting_name)
Initiate standalone name resolution.
Definition: nslookup.c:150
Single foreground job.
#define ENOMEM
Not enough space.
Definition: errno.h:535
static struct interface_operation nslookup_job_operations[]
Name resolution job control interface operations.
Definition: nslookup.c:133
FILE_LICENCE(GPL2_OR_LATER)
An object interface.
Definition: interface.h:125
FILE_SECBOOT(PERMITTED)
ring len
Length.
Definition: dwmac.h:231
struct interface resolver
Data transfer interface.
Definition: nslookup.c:47
struct sockaddr sa
Definition: syslog.c:57
Transport-network layer interface.
char * strcpy(char *dest, const char *src)
Copy string.
Definition: string.c:347
const struct setting_type * type
Setting type.
Definition: settings.h:37
struct settings * autovivify_child_settings(struct settings *parent, const char *name)
Find or create child settings block.
Definition: settings.c:307
struct interface monojob
Definition: monojob.c:57
Configuration settings.
static struct interface_operation nslookup_resolver_operations[]
Name resolution resolver interface operations.
Definition: nslookup.c:122
Generalized socket address structure.
Definition: socket.h:97
An object interface descriptor.
Definition: interface.h:56
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:662
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:33
static struct interface_descriptor nslookup_job_desc
Name resolution job control interface descriptor.
Definition: nslookup.c:138
size_t strlen(const char *src)
Get length of string.
Definition: string.c:244
A settings block.
Definition: settings.h:133
A setting.
Definition: settings.h:24
int nslookup(const char *name, const char *setting_name)
Perform (blocking) standalone name resolution.
Definition: nslookup.c:192
struct in_addr sin_addr
IPv4 address.
Definition: in.h:101
static void nslookup_resolv_done(struct nslookup *nslookup, struct sockaddr *sa)
Handle resolved name.
Definition: nslookup.c:72
A name resolver.
Definition: resolv.h:19
uint8_t data[48]
Additional event data.
Definition: ena.h:22
IPv6 socket address.
Definition: in.h:118
int resolv(struct interface *resolv, const char *name, struct sockaddr *sa)
Start name resolution.
Definition: resolv.c:258
#define INTF_DESC_PASSTHRU(object_type, intf, operations, passthru)
Define an object interface descriptor with pass-through interface.
Definition: interface.h:98
struct sockaddr_in sin
Definition: syslog.c:59
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition: interface.h:204
int setting_name(struct settings *settings, const struct setting *setting, char *buf, size_t len)
Return full setting name.
Definition: settings.c:1607
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
String functions.
#define AF_INET
IPv4 Internet addresses.
Definition: socket.h:64
A setting type.
Definition: settings.h:192
int parse_setting_name(char *name, get_child_settings_t get_child, struct settings **settings, struct setting *setting)
Parse setting name.
Definition: settings.c:1529
struct in6_addr sin6_addr
IPv6 address.
Definition: in.h:135
A name resolution request.
Definition: nslookup.c:40
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:107
void * memset(void *dest, int character, size_t len) __nonnull