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
);