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 /* 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 */
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 */
143int 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 */
171int 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 */
203int 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 */
225int 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}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
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:505
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
#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:926
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:225
int xfer_open_socket(struct interface *intf, int semantics, struct sockaddr *peer, struct sockaddr *local)
Open socket.
Definition open.c:143
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:203
int xfer_vopen(struct interface *intf, int type, va_list args)
Open location.
Definition open.c:171
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:116
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 void uri_put(struct uri *uri)
Decrement URI reference count.
Definition uri.h:206
Data transfer interfaces.