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
24FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25FILE_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 */
48struct uri_opener * xfer_uri_opener ( const char *scheme ) {
49 struct uri_opener *opener;
50
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 */
68int 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 /* Check that URI has a scheme */
81 if ( ! uri_is_absolute ( resolved_uri ) ) {
82 DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " attempted to open "
83 "non-absolute URI\n", INTF_DBG ( intf ) );
84 rc = -ENOTSUP;
85 goto err_absolute;
86 }
87
88 /* Find opener which supports this URI scheme */
89 opener = xfer_uri_opener ( resolved_uri->scheme );
90 if ( ! opener ) {
91 DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " attempted to open "
92 "unsupported URI scheme \"%s\"\n",
93 INTF_DBG ( intf ), resolved_uri->scheme );
94 rc = -ENOTSUP;
95 goto err_opener;
96 }
97
98 /* Call opener */
99 DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " opening %s URI\n",
100 INTF_DBG ( intf ), resolved_uri->scheme );
101 if ( ( rc = opener->open ( intf, resolved_uri ) ) != 0 ) {
102 DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " could not open: "
103 "%s\n", INTF_DBG ( intf ), strerror ( rc ) );
104 goto err_open;
105 }
106
107 err_open:
108 err_opener:
109 err_absolute:
110 uri_put ( resolved_uri );
111 err_resolve_uri:
112 return rc;
113}
114
115/**
116 * Open URI string
117 *
118 * @v intf Data transfer interface
119 * @v uri_string URI string (e.g. "http://ipxe.org/kernel")
120 * @ret rc Return status code
121 *
122 * The URI will be regarded as being relative to the current working
123 * URI (see churi()).
124 */
126 const char *uri_string ) {
127 struct uri *uri;
128 int rc;
129
130 DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " opening URI %s\n",
131 INTF_DBG ( intf ), uri_string );
132
133 uri = parse_uri ( uri_string );
134 if ( ! uri )
135 return -ENOMEM;
136
137 rc = xfer_open_uri ( intf, uri );
138
139 uri_put ( uri );
140 return rc;
141}
142
143/**
144 * Open socket
145 *
146 * @v intf Data transfer interface
147 * @v semantics Communication semantics (e.g. SOCK_STREAM)
148 * @v peer Peer socket address
149 * @v local Local socket address, or NULL
150 * @ret rc Return status code
151 */
152int xfer_open_socket ( struct interface *intf, int semantics,
153 struct sockaddr *peer, struct sockaddr *local ) {
154 struct socket_opener *opener;
155
156 DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " opening (%s,%s) socket\n",
158 socket_family_name ( peer->sa_family ) );
159
161 if ( opener->semantics == semantics )
162 return opener->open ( intf, peer, local );
163 }
164
165 DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " attempted to open "
166 "unsupported socket type (%s,%s)\n",
168 socket_family_name ( peer->sa_family ) );
169 return -ENOTSUP;
170}
171
172/**
173 * Open location
174 *
175 * @v intf Data transfer interface
176 * @v type Location type
177 * @v args Remaining arguments depend upon location type
178 * @ret rc Return status code
179 */
180int xfer_vopen ( struct interface *intf, int type, va_list args ) {
181 switch ( type ) {
182 case LOCATION_URI_STRING: {
183 const char *uri_string = va_arg ( args, const char * );
184
185 return xfer_open_uri_string ( intf, uri_string ); }
186 case LOCATION_URI: {
187 struct uri *uri = va_arg ( args, struct uri * );
188
189 return xfer_open_uri ( intf, uri ); }
190 case LOCATION_SOCKET: {
191 int semantics = va_arg ( args, int );
192 struct sockaddr *peer = va_arg ( args, struct sockaddr * );
193 struct sockaddr *local = va_arg ( args, struct sockaddr * );
194
195 return xfer_open_socket ( intf, semantics, peer, local ); }
196 default:
197 DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " attempted to "
198 "open unsupported location type %d\n",
199 INTF_DBG ( intf ), type );
200 return -ENOTSUP;
201 }
202}
203
204/**
205 * Open location
206 *
207 * @v intf Data transfer interface
208 * @v type Location type
209 * @v ... Remaining arguments depend upon location type
210 * @ret rc Return status code
211 */
212int xfer_open ( struct interface *intf, int type, ... ) {
213 va_list args;
214 int rc;
215
216 va_start ( args, type );
217 rc = xfer_vopen ( intf, type, args );
218 va_end ( args );
219 return rc;
220}
221
222/**
223 * Reopen location
224 *
225 * @v intf Data transfer interface
226 * @v type Location type
227 * @v args Remaining arguments depend upon location type
228 * @ret rc Return status code
229 *
230 * This will close the existing connection and open a new connection
231 * using xfer_vopen(). It is intended to be used as a .vredirect
232 * method handler.
233 */
234int xfer_vreopen ( struct interface *intf, int type, va_list args ) {
235
236 /* Close existing connection */
237 intf_restart ( intf, 0 );
238
239 /* Open new location */
240 return xfer_vopen ( intf, type, args );
241}
#define NULL
NULL pointer (VOID *).
Definition Base.h:321
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
struct uri * cwuri
Current working URI.
Definition cwuri.c:39
uint32_t type
Operating system type.
Definition ena.h:1
Error codes.
#define DBGC(...)
Definition compiler.h:530
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:921
#define ENOMEM
Not enough space.
Definition errno.h:535
#define ENOTSUP
Operation not supported.
Definition errno.h:590
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:951
String functions.
String functions.
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition interface.c:344
#define INTF_DBG(intf)
printf() arguments for representing an object interface
Definition interface.h:293
#define INTF_COL(intf)
Find debugging colourisation for an object interface.
Definition interface.h:282
#define INTF_FMT
printf() format string for INTF_DBG()
Definition interface.h:285
struct mschapv2_challenge peer
Peer challenge.
Definition mschapv2.h:1
int xfer_vreopen(struct interface *intf, int type, va_list args)
Reopen location.
Definition open.c:234
int xfer_open_socket(struct interface *intf, int semantics, struct sockaddr *peer, struct sockaddr *local)
Open socket.
Definition open.c:152
int xfer_open_uri(struct interface *intf, struct uri *uri)
Open URI.
Definition open.c:68
int xfer_open(struct interface *intf, int type,...)
Open location.
Definition open.c:212
int xfer_vopen(struct interface *intf, int type, va_list args)
Open location.
Definition open.c:180
struct uri_opener * xfer_uri_opener(const char *scheme)
Find opener for URI scheme.
Definition open.c:48
int xfer_open_uri_string(struct interface *intf, const char *uri_string)
Open URI string.
Definition open.c:125
Data transfer interface opening.
#define SOCKET_OPENERS
Socket opener table.
Definition open.h:86
@ LOCATION_SOCKET
Location is a socket.
Definition open.h:44
@ LOCATION_URI
Location is a URI.
Definition open.h:28
@ LOCATION_URI_STRING
Location is a URI string.
Definition open.h:35
#define URI_OPENERS
URI opener table.
Definition open.h:65
Socket addresses.
static const char * socket_semantics_name(int semantics)
Name communication semantics.
Definition socket.h:46
static const char * socket_family_name(int family)
Name address family.
Definition socket.h:76
#define va_arg(ap, type)
Definition stdarg.h:9
#define va_end(ap)
Definition stdarg.h:10
#define va_start(ap, last)
Definition stdarg.h:8
__builtin_va_list va_list
Definition stdarg.h:7
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
int strcasecmp(const char *first, const char *second)
Compare case-insensitive strings.
Definition string.c:209
An object interface.
Definition interface.h:125
Generalized socket address structure.
Definition socket.h:97
A socket opener.
Definition open.h:71
int(* open)(struct interface *intf, struct sockaddr *peer, struct sockaddr *local)
Open socket.
Definition open.h:81
int semantics
Communication semantics (e.g.
Definition open.h:73
A URI opener.
Definition open.h:48
const char * scheme
URI protocol name.
Definition open.h:54
int(* open)(struct interface *intf, struct uri *uri)
Open URI.
Definition open.h:61
A Uniform Resource Identifier.
Definition uri.h:65
const char * scheme
Scheme.
Definition uri.h:69
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition tables.h:386
struct uri * parse_uri(const char *uri_string)
Parse URI.
Definition uri.c:297
struct uri * resolve_uri(const struct uri *base_uri, struct uri *relative_uri)
Resolve base+relative URI.
Definition uri.c:696
Uniform Resource Identifiers.
static int uri_is_absolute(const struct uri *uri)
URI is an absolute URI.
Definition uri.h:136
static void uri_put(struct uri *uri)
Decrement URI reference count.
Definition uri.h:206
Data transfer interfaces.