iPXE
open.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
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  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 FILE_SECBOOT ( PERMITTED );
26 
27 #include <stdarg.h>
28 #include <string.h>
29 #include <strings.h>
30 #include <errno.h>
31 #include <ipxe/xfer.h>
32 #include <ipxe/uri.h>
33 #include <ipxe/socket.h>
34 #include <ipxe/open.h>
35 
36 /** @file
37  *
38  * Data transfer interface opening
39  *
40  */
41 
42 /**
43  * Find opener for URI scheme
44  *
45  * @v scheme URI scheme
46  * @ret opener Opener, or NULL
47  */
48 struct uri_opener * xfer_uri_opener ( const char *scheme ) {
49  struct uri_opener *opener;
50 
51  for_each_table_entry ( opener, URI_OPENERS ) {
52  if ( strcasecmp ( scheme, opener->scheme ) == 0 )
53  return opener;
54  }
55  return NULL;
56 }
57 
58 /**
59  * Open URI
60  *
61  * @v intf Data transfer interface
62  * @v uri URI
63  * @ret rc Return status code
64  *
65  * The URI will be regarded as being relative to the current working
66  * URI (see churi()).
67  */
68 int xfer_open_uri ( struct interface *intf, struct uri *uri ) {
69  struct uri_opener *opener;
70  struct uri *resolved_uri;
71  int rc;
72 
73  /* Resolve URI */
74  resolved_uri = resolve_uri ( cwuri, uri );
75  if ( ! resolved_uri ) {
76  rc = -ENOMEM;
77  goto err_resolve_uri;
78  }
79 
80  /* Find opener which supports this URI scheme */
81  opener = xfer_uri_opener ( resolved_uri->scheme );
82  if ( ! opener ) {
83  DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " attempted to open "
84  "unsupported URI scheme \"%s\"\n",
85  INTF_DBG ( intf ), resolved_uri->scheme );
86  rc = -ENOTSUP;
87  goto err_opener;
88  }
89 
90  /* Call opener */
91  DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " opening %s URI\n",
92  INTF_DBG ( intf ), resolved_uri->scheme );
93  if ( ( rc = opener->open ( intf, resolved_uri ) ) != 0 ) {
94  DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " could not open: "
95  "%s\n", INTF_DBG ( intf ), strerror ( rc ) );
96  goto err_open;
97  }
98 
99  err_open:
100  err_opener:
101  uri_put ( resolved_uri );
102  err_resolve_uri:
103  return rc;
104 }
105 
106 /**
107  * Open URI string
108  *
109  * @v intf Data transfer interface
110  * @v uri_string URI string (e.g. "http://ipxe.org/kernel")
111  * @ret rc Return status code
112  *
113  * The URI will be regarded as being relative to the current working
114  * URI (see churi()).
115  */
116 int xfer_open_uri_string ( struct interface *intf,
117  const char *uri_string ) {
118  struct uri *uri;
119  int rc;
120 
121  DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " opening URI %s\n",
122  INTF_DBG ( intf ), uri_string );
123 
124  uri = parse_uri ( uri_string );
125  if ( ! uri )
126  return -ENOMEM;
127 
128  rc = xfer_open_uri ( intf, uri );
129 
130  uri_put ( uri );
131  return rc;
132 }
133 
134 /**
135  * Open socket
136  *
137  * @v intf Data transfer interface
138  * @v semantics Communication semantics (e.g. SOCK_STREAM)
139  * @v peer Peer socket address
140  * @v local Local socket address, or NULL
141  * @ret rc Return status code
142  */
143 int xfer_open_socket ( struct interface *intf, int semantics,
144  struct sockaddr *peer, struct sockaddr *local ) {
145  struct socket_opener *opener;
146 
147  DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " opening (%s,%s) socket\n",
149  socket_family_name ( peer->sa_family ) );
150 
152  if ( opener->semantics == semantics )
153  return opener->open ( intf, peer, local );
154  }
155 
156  DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " attempted to open "
157  "unsupported socket type (%s,%s)\n",
159  socket_family_name ( peer->sa_family ) );
160  return -ENOTSUP;
161 }
162 
163 /**
164  * Open location
165  *
166  * @v intf Data transfer interface
167  * @v type Location type
168  * @v args Remaining arguments depend upon location type
169  * @ret rc Return status code
170  */
171 int xfer_vopen ( struct interface *intf, int type, va_list args ) {
172  switch ( type ) {
173  case LOCATION_URI_STRING: {
174  const char *uri_string = va_arg ( args, const char * );
175 
176  return xfer_open_uri_string ( intf, uri_string ); }
177  case LOCATION_URI: {
178  struct uri *uri = va_arg ( args, struct uri * );
179 
180  return xfer_open_uri ( intf, uri ); }
181  case LOCATION_SOCKET: {
182  int semantics = va_arg ( args, int );
183  struct sockaddr *peer = va_arg ( args, struct sockaddr * );
184  struct sockaddr *local = va_arg ( args, struct sockaddr * );
185 
186  return xfer_open_socket ( intf, semantics, peer, local ); }
187  default:
188  DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " attempted to "
189  "open unsupported location type %d\n",
190  INTF_DBG ( intf ), type );
191  return -ENOTSUP;
192  }
193 }
194 
195 /**
196  * Open location
197  *
198  * @v intf Data transfer interface
199  * @v type Location type
200  * @v ... Remaining arguments depend upon location type
201  * @ret rc Return status code
202  */
203 int xfer_open ( struct interface *intf, int type, ... ) {
204  va_list args;
205  int rc;
206 
207  va_start ( args, type );
208  rc = xfer_vopen ( intf, type, args );
209  va_end ( args );
210  return rc;
211 }
212 
213 /**
214  * Reopen location
215  *
216  * @v intf Data transfer interface
217  * @v type Location type
218  * @v args Remaining arguments depend upon location type
219  * @ret rc Return status code
220  *
221  * This will close the existing connection and open a new connection
222  * using xfer_vopen(). It is intended to be used as a .vredirect
223  * method handler.
224  */
225 int xfer_vreopen ( struct interface *intf, int type, va_list args ) {
226 
227  /* Close existing connection */
228  intf_restart ( intf, 0 );
229 
230  /* Open new location */
231  return xfer_vopen ( intf, type, args );
232 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition: interface.c:344
#define va_end(ap)
Definition: stdarg.h:10
static const char * socket_semantics_name(int semantics)
Name communication semantics.
Definition: socket.h:46
#define INTF_DBG(intf)
printf() arguments for representing an object interface
Definition: interface.h:293
static void uri_put(struct uri *uri)
Decrement URI reference count.
Definition: uri.h:206
#define URI_OPENERS
URI opener table.
Definition: open.h:65
Error codes.
int xfer_open_socket(struct interface *intf, int semantics, struct sockaddr *peer, struct sockaddr *local)
Open socket.
Definition: open.c:143
uint32_t type
Operating system type.
Definition: ena.h:12
int xfer_open_uri(struct interface *intf, struct uri *uri)
Open URI.
Definition: open.c:68
#define INTF_COL(intf)
Find debugging colourisation for an object interface.
Definition: interface.h:282
#define DBGC(...)
Definition: compiler.h:505
FILE_SECBOOT(PERMITTED)
int strcasecmp(const char *first, const char *second)
Compare case-insensitive strings.
Definition: string.c:209
Uniform Resource Identifiers.
int semantics
Communication semantics (e.g.
Definition: open.h:73
#define ENOTSUP
Operation not supported.
Definition: errno.h:590
Data transfer interfaces.
Location is a socket.
Definition: open.h:44
#define ENOMEM
Not enough space.
Definition: errno.h:535
const char * scheme
Scheme.
Definition: uri.h:69
int(* open)(struct interface *intf, struct uri *uri)
Open URI.
Definition: open.h:61
#define va_arg(ap, type)
Definition: stdarg.h:9
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
#define SOCKET_OPENERS
Socket opener table.
Definition: open.h:86
Location is a URI string.
Definition: open.h:35
An object interface.
Definition: interface.h:125
Location is a URI.
Definition: open.h:28
const char * scheme
URI protocol name.
Definition: open.h:54
Generalized socket address structure.
Definition: socket.h:97
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition: tables.h:386
static const char * socket_family_name(int family)
Name address family.
Definition: socket.h:76
Data transfer interface opening.
int xfer_open(struct interface *intf, int type,...)
Open location.
Definition: open.c:203
int xfer_vreopen(struct interface *intf, int type, va_list args)
Reopen location.
Definition: open.c:225
int(* open)(struct interface *intf, struct sockaddr *peer, struct sockaddr *local)
Open socket.
Definition: open.h:81
__builtin_va_list va_list
Definition: stdarg.h:7
int xfer_vopen(struct interface *intf, int type, va_list args)
Open location.
Definition: open.c:171
A Uniform Resource Identifier.
Definition: uri.h:65
struct mschapv2_challenge peer
Peer challenge.
Definition: mschapv2.h:12
struct uri_opener * xfer_uri_opener(const char *scheme)
Find opener for URI scheme.
Definition: open.c:48
struct uri * resolve_uri(const struct uri *base_uri, struct uri *relative_uri)
Resolve base+relative URI.
Definition: uri.c:695
#define va_start(ap, last)
Definition: stdarg.h:8
struct uri * cwuri
Current working URI.
Definition: cwuri.c:39
int xfer_open_uri_string(struct interface *intf, const char *uri_string)
Open URI string.
Definition: open.c:116
Socket addresses.
A URI opener.
Definition: open.h:48
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
String functions.
String functions.
struct uri * parse_uri(const char *uri_string)
Parse URI.
Definition: uri.c:297
#define INTF_FMT
printf() format string for INTF_DBG()
Definition: interface.h:285
A socket opener.
Definition: open.h:71