2 * Copyright (C) 2013 Marin Hannache <ipxe@mareo.fr>.
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.
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.
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
27 #include <ipxe/socket.h>
28 #include <ipxe/tcpip.h>
30 #include <ipxe/iobuf.h>
31 #include <ipxe/xfer.h>
32 #include <ipxe/open.h>
34 #include <ipxe/features.h>
35 #include <ipxe/oncrpc.h>
36 #include <ipxe/oncrpc_iob.h>
40 * SUN ONC RPC protocol
44 size_t oncrpc_iob_add_fields ( struct io_buffer *io_buf,
45 const struct oncrpc_field fields[] ) {
49 struct oncrpc_field f;
54 for ( i = 0; fields[i].type != oncrpc_none; i++ ) {
58 s += oncrpc_iob_add_int ( io_buf, f.value.int32 );
62 s += oncrpc_iob_add_int64 ( io_buf, f.value.int64 );
66 s += oncrpc_iob_add_string ( io_buf, f.value.str );
70 s += oncrpc_iob_add_array ( io_buf,
76 s += oncrpc_iob_add_intarray ( io_buf,
77 f.value.intarray.length,
78 f.value.intarray.ptr );
82 s += oncrpc_iob_add_cred ( io_buf, f.value.cred);
94 * Add an array of bytes to the end of an I/O buffer
96 * @v io_buf I/O buffer
98 * @ret size Size of the data written
100 * In the ONC RPC protocol, every data is four byte paded, we add padding when
101 * necessary by using oncrpc_align()
103 size_t oncrpc_iob_add_array ( struct io_buffer *io_buf, size_t length,
105 size_t padding = oncrpc_align ( length ) - length;
107 oncrpc_iob_add_int ( io_buf, length );
108 memcpy ( iob_put ( io_buf, length ), data, length );
109 memset ( iob_put ( io_buf, padding ), 0, padding );
111 return length + padding + sizeof ( uint32_t );
115 * Add an int array to the end of an I/O buffer
117 * @v io_buf I/O buffer
118 * @v length Length od the array
120 * @ret size Size of the data written
122 size_t oncrpc_iob_add_intarray ( struct io_buffer *io_buf, size_t length,
123 const uint32_t *array ) {
126 oncrpc_iob_add_int ( io_buf, length );
128 for ( i = 0; i < length; ++i )
129 oncrpc_iob_add_int ( io_buf, array[i] );
131 return ( ( length + 1 ) * sizeof ( uint32_t ) );
135 * Add credential information to the end of an I/O buffer
137 * @v io_buf I/O buffer
138 * @v cred Credential information
139 * @ret size Size of the data written
141 size_t oncrpc_iob_add_cred ( struct io_buffer *io_buf,
142 const struct oncrpc_cred *cred ) {
143 struct oncrpc_cred_sys *syscred;
146 struct oncrpc_field credfields[] = {
147 ONCRPC_FIELD ( int32, cred->flavor ),
148 ONCRPC_FIELD ( int32, cred->length ),
152 if ( ! io_buf || ! cred )
155 s = oncrpc_iob_add_fields ( io_buf, credfields);
157 switch ( cred->flavor ) {
158 case ONCRPC_AUTH_NONE:
161 case ONCRPC_AUTH_SYS:
162 syscred = container_of ( cred, struct oncrpc_cred_sys,
165 struct oncrpc_field syscredfields[] = {
166 ONCRPC_FIELD ( int32, syscred->stamp ),
167 ONCRPC_FIELD ( str, syscred->hostname ),
168 ONCRPC_FIELD ( int32, syscred->uid ),
169 ONCRPC_FIELD ( int32, syscred->gid ),
170 ONCRPC_SUBFIELD ( intarray, syscred->aux_gid_len,
175 s += oncrpc_iob_add_fields ( io_buf, syscredfields );
183 * Get credential information from the beginning of an I/O buffer
185 * @v io_buf I/O buffer
186 * @v cred Struct where the information will be saved
187 * @ret size Size of the data read
189 size_t oncrpc_iob_get_cred ( struct io_buffer *io_buf,
190 struct oncrpc_cred *cred ) {
192 return * ( uint32_t * ) io_buf->data;
194 cred->flavor = oncrpc_iob_get_int ( io_buf );
195 cred->length = oncrpc_iob_get_int ( io_buf );
197 iob_pull ( io_buf, cred->length );
199 return ( 2 * sizeof ( uint32_t ) + cred->length );