iPXE
pccrr.h
Go to the documentation of this file.
00001 #ifndef _IPXE_PCCRR_H
00002 #define _IPXE_PCCRR_H
00003 
00004 /** @file
00005  *
00006  * Peer Content Caching and Retrieval: Retrieval Protocol [MS-PCCRR]
00007  *
00008  * All fields are in network byte order.
00009  *
00010  */
00011 
00012 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
00013 
00014 #include <stdint.h>
00015 #include <ipxe/uaccess.h>
00016 
00017 /** Magic retrieval URI path */
00018 #define PEERDIST_MAGIC_PATH "/116B50EB-ECE2-41ac-8429-9F9E963361B7/"
00019 
00020 /** Retrieval protocol version */
00021 union peerdist_msg_version {
00022         /** Raw version number */
00023         uint32_t raw;
00024         /** Major:minor version number */
00025         struct {
00026                 /** Minor version number */
00027                 uint16_t minor;
00028                 /** Major version number */
00029                 uint16_t major;
00030         } __attribute__ (( packed ));
00031 } __attribute__ (( packed ));
00032 
00033 /** Retrieval protocol version 1.0 */
00034 #define PEERDIST_MSG_VERSION_1_0 0x00000001UL
00035 
00036 /** Retrieval protocol version 2.0 */
00037 #define PEERDIST_MSG_VERSION_2_0 0x00000002UL
00038 
00039 /** Retrieval protocol supported versions */
00040 struct peerdist_msg_versions {
00041         /** Minimum supported protocol version */
00042         union peerdist_msg_version min;
00043         /** Maximum supported protocol version */
00044         union peerdist_msg_version max;
00045 } __attribute__ (( packed ));
00046 
00047 /** Retrieval protocol block range */
00048 struct peerdist_msg_range {
00049         /** First block in range */
00050         uint32_t first;
00051         /** Number of blocks in range */
00052         uint32_t count;
00053 } __attribute__ (( packed ));
00054 
00055 /** Retrieval protocol segment ID header */
00056 struct peerdist_msg_segment {
00057         /** Digest size (i.e. length of segment ID) */
00058         uint32_t digestsize;
00059         /* Followed by a single variable-length ID and padding:
00060          *
00061          * uint8_t id[digestsize];
00062          * uint8_t pad[ (-digestsize) & 0x3 ];
00063          */
00064 } __attribute__ (( packed ));
00065 
00066 /** Retrieval protocol segment ID
00067  *
00068  * @v digestsize        Digest size
00069  */
00070 #define peerdist_msg_segment_t( digestsize )                            \
00071         struct {                                                        \
00072                 struct peerdist_msg_segment segment;                    \
00073                 uint8_t id[digestsize];                                 \
00074                 uint8_t pad[ ( -(digestsize) ) & 0x3 ];                 \
00075         } __attribute__ (( packed ))
00076 
00077 /** Retrieval protocol block range list header */
00078 struct peerdist_msg_ranges {
00079         /** Number of ranges */
00080         uint32_t count;
00081         /* Followed by an array of block ranges:
00082          *
00083          * struct peerdist_msg_range range[count];
00084          */
00085 } __attribute__ (( packed ));
00086 
00087 /** Retrieval protocol block range list
00088  *
00089  * @v count             Number of ranges
00090  */
00091 #define peerdist_msg_ranges_t( count )                                  \
00092         struct {                                                        \
00093                 struct peerdist_msg_ranges ranges;                      \
00094                 struct peerdist_msg_range range[count];                 \
00095         } __attribute__ (( packed ))
00096 
00097 /** Retrieval protocol data block header */
00098 struct peerdist_msg_block {
00099         /** Length of data block */
00100         uint32_t len;
00101         /* Followed by the (encrypted) data block:
00102          *
00103          * uint8_t data[len];
00104          */
00105 } __attribute__ (( packed ));
00106 
00107 /** Retrieval protocol data block */
00108 #define peerdist_msg_block_t( len )                                     \
00109         struct {                                                        \
00110                 struct peerdist_msg_block block;                        \
00111                 uint8_t data[len];                                      \
00112         } __attribute__ (( packed ))
00113 
00114 /** Retrieval protocol initialisation vector header */
00115 struct peerdist_msg_iv {
00116         /** Cipher block size */
00117         uint32_t blksize;
00118         /* Followed by the initialisation vector:
00119          *
00120          * uint8_t data[blksize];
00121          */
00122 } __attribute__ (( packed ));
00123 
00124 /** Retrieval protocol initialisation vector */
00125 #define peerdist_msg_iv_t( blksize )                                    \
00126         struct {                                                        \
00127                 struct peerdist_msg_iv iv;                              \
00128                 uint8_t data[blksize];                                  \
00129         } __attribute__ (( packed ))
00130 
00131 /** Retrieval protocol useless VRF data header */
00132 struct peerdist_msg_useless_vrf {
00133         /** Length of useless VRF data */
00134         uint32_t len;
00135         /* Followed by a variable-length useless VRF data block and
00136          * padding:
00137          *
00138          * uint8_t data[len];
00139          * uint8_t pad[ (-len) & 0x3 ];
00140          */
00141 } __attribute__ (( packed ));
00142 
00143 /** Retrieval protocol useless VRF data */
00144 #define peerdist_msg_useless_vrf_t( vrf_len )                           \
00145         struct {                                                        \
00146                 struct peerdist_msg_useless_vrf vrf;                    \
00147                 uint8_t data[vrf_len];                                  \
00148                 uint8_t pad[ ( -(vrf_len) ) & 0x3 ];                    \
00149         } __attribute__ (( packed ))
00150 
00151 /** Retrieval protocol message header */
00152 struct peerdist_msg_header {
00153         /** Protocol version
00154          *
00155          * This is the protocol version in which the message type was
00156          * first defined.
00157          */
00158         union peerdist_msg_version version;
00159         /** Message type */
00160         uint32_t type;
00161         /** Message size (including this header) */
00162         uint32_t len;
00163         /** Cryptographic algorithm ID */
00164         uint32_t algorithm;
00165 } __attribute__ (( packed ));
00166 
00167 /** Retrieval protocol cryptographic algorithm IDs */
00168 enum peerdist_msg_algorithm {
00169         /** No encryption */
00170         PEERDIST_MSG_PLAINTEXT = 0x00000000UL,
00171         /** AES-128 in CBC mode */
00172         PEERDIST_MSG_AES_128_CBC = 0x00000001UL,
00173         /** AES-192 in CBC mode */
00174         PEERDIST_MSG_AES_192_CBC = 0x00000002UL,
00175         /** AES-256 in CBC mode */
00176         PEERDIST_MSG_AES_256_CBC = 0x00000003UL,
00177 };
00178 
00179 /** Retrieval protocol transport response header */
00180 struct peerdist_msg_transport_header {
00181         /** Length (excluding this header)
00182          *
00183          * This seems to be identical in both purpose and value to the
00184          * length found within the message header, and therefore
00185          * serves no useful purpose.
00186          */
00187         uint32_t len;
00188 } __attribute__ (( packed ));
00189 
00190 /** Retrieval protocol negotiation request */
00191 struct peerdist_msg_nego_req {
00192         /** Message header */
00193         struct peerdist_msg_header hdr;
00194         /** Supported versions */
00195         struct peerdist_msg_versions versions;
00196 } __attribute__ (( packed ));
00197 
00198 /** Retrieval protocol negotiation request version */
00199 #define PEERDIST_MSG_NEGO_REQ_VERSION PEERDIST_MSG_VERSION_1_0
00200 
00201 /** Retrieval protocol negotiation request type */
00202 #define PEERDIST_MSG_NEGO_REQ_TYPE 0x00000000UL
00203 
00204 /** Retrieval protocol negotiation response */
00205 struct peerdist_msg_nego_resp {
00206         /** Message header */
00207         struct peerdist_msg_header hdr;
00208         /** Supported versions */
00209         struct peerdist_msg_versions versions;
00210 } __attribute__ (( packed ));
00211 
00212 /** Retrieval protocol negotiation response version */
00213 #define PEERDIST_MSG_NEGO_RESP_VERSION PEERDIST_MSG_VERSION_1_0
00214 
00215 /** Retrieval protocol negotiation response type */
00216 #define PEERDIST_MSG_NEGO_RESP_TYPE 0x00000001UL
00217 
00218 /** Retrieval protocol block list request header */
00219 struct peerdist_msg_getblklist {
00220         /** Message header */
00221         struct peerdist_msg_header hdr;
00222         /* Followed by a segment ID and a block range list:
00223          *
00224          * peerdist_msg_segment_t(digestsize) segment;
00225          * peerdist_msg_ranges_t(count) ranges;
00226          */
00227 } __attribute__ (( packed ));
00228 
00229 /** Retrieval protocol block list request
00230  *
00231  * @v digestsize        Digest size
00232  * @v count             Block range count
00233  */
00234 #define peerdist_msg_getblklist_t( digestsize, count )                  \
00235         struct {                                                        \
00236                 struct peerdist_msg_getblklist getblklist;              \
00237                 peerdist_msg_segment_t ( digestsize ) segment;          \
00238                 peerdist_msg_ranges_t ( count ) ranges;                 \
00239         } __attribute__ (( packed ))
00240 
00241 /** Retrieval protocol block list request version */
00242 #define PEERDIST_MSG_GETBLKLIST_VERSION PEERDIST_MSG_VERSION_1_0
00243 
00244 /** Retrieval protocol block list request type */
00245 #define PEERDIST_MSG_GETBLKLIST_TYPE 0x00000002UL
00246 
00247 /** Retrieval protocol block fetch request header */
00248 struct peerdist_msg_getblks {
00249         /** Message header */
00250         struct peerdist_msg_header hdr;
00251         /* Followed by a segment ID, a block range list, and a useless
00252          * VRF block:
00253          *
00254          * peerdist_msg_segment_t(digestsize) segment;
00255          * peerdist_msg_ranges_t(count) ranges;
00256          * peerdist_msg_vrf_t(vrf_len) vrf;
00257          */
00258 } __attribute__ (( packed ));
00259 
00260 /** Retrieval protocol block fetch request
00261  *
00262  * @v digestsize        Digest size
00263  * @v count             Block range count
00264  * @v vrf_len           Length of uselessness
00265  */
00266 #define peerdist_msg_getblks_t( digestsize, count, vrf_len )            \
00267         struct {                                                        \
00268                 struct peerdist_msg_getblks getblks;                    \
00269                 peerdist_msg_segment_t ( digestsize ) segment;          \
00270                 peerdist_msg_ranges_t ( count ) ranges;                 \
00271                 peerdist_msg_useless_vrf_t ( vrf_len );                 \
00272         } __attribute__ (( packed ))
00273 
00274 /** Retrieval protocol block fetch request version */
00275 #define PEERDIST_MSG_GETBLKS_VERSION PEERDIST_MSG_VERSION_1_0
00276 
00277 /** Retrieval protocol block fetch request type */
00278 #define PEERDIST_MSG_GETBLKS_TYPE 0x00000003UL
00279 
00280 /** Retrieval protocol block list response header */
00281 struct peerdist_msg_blklist {
00282         /** Message header */
00283         struct peerdist_msg_header hdr;
00284         /* Followed by a segment ID, a block range list, and a next
00285          * block index:
00286          *
00287          * peerdist_msg_segment_t(digestsize) segment;
00288          * peerdist_msg_ranges_t(count) ranges;
00289          * uint32_t next;
00290          */
00291 } __attribute__ (( packed ));
00292 
00293 /** Retrieval protocol block list response
00294  *
00295  * @v digestsize        Digest size
00296  * @v count             Block range count
00297  */
00298 #define peerdist_msg_blklist_t( digestsize, count )                     \
00299         struct {                                                        \
00300                 struct peerdist_msg_blklist blklist;                    \
00301                 peerdist_msg_segment_t ( digestsize ) segment;          \
00302                 peerdist_msg_ranges_t ( count ) ranges;                 \
00303                 uint32_t next;                                          \
00304         } __attribute__ (( packed ))
00305 
00306 /** Retrieval protocol block list response version */
00307 #define PEERDIST_MSG_BLKLIST_VERSION PEERDIST_MSG_VERSION_1_0
00308 
00309 /** Retrieval protocol block list response type */
00310 #define PEERDIST_MSG_BLKLIST_TYPE 0x00000004UL
00311 
00312 /** Retrieval protocol block fetch response header */
00313 struct peerdist_msg_blk {
00314         /** Message header */
00315         struct peerdist_msg_header hdr;
00316         /* Followed by a segment ID, a block index, a next block
00317          * index, a data block, a useless VRF block, and an
00318          * initialisation vector:
00319          *
00320          * peerdist_msg_segment_t(digestsize) segment;
00321          * uint32_t index;
00322          * uint32_t next;
00323          * peerdist_msg_block_t(len) data;
00324          * peerdist_msg_useless_vrf_t(vrf_len) vrf;
00325          * peerdist_msg_iv_t(blksize) iv;
00326          */
00327 } __attribute__ (( packed ));
00328 
00329 /** Retrieval protocol block fetch response
00330  *
00331  * @v digestsize        Digest size
00332  * @v len               Data block length
00333  * @v vrf_len           Length of uselessness
00334  * @v blksize           Cipher block size
00335  */
00336 #define peerdist_msg_blk_t( digestsize, len, vrf_len, blksize )         \
00337         struct {                                                        \
00338                 struct peerdist_msg_blk blk;                            \
00339                 peerdist_msg_segment_t ( digestsize ) segment;          \
00340                 uint32_t index;                                         \
00341                 uint32_t next;                                          \
00342                 peerdist_msg_block_t ( len ) block;                     \
00343                 peerdist_msg_useless_vrf_t ( vrf_len ) vrf;             \
00344                 peerdist_msg_iv_t ( blksize ) iv;                       \
00345         } __attribute__ (( packed ))
00346 
00347 /** Retrieval protocol block fetch response version */
00348 #define PEERDIST_MSG_BLK_VERSION PEERDIST_MSG_VERSION_1_0
00349 
00350 /** Retrieval protocol block fetch response type */
00351 #define PEERDIST_MSG_BLK_TYPE 0x00000005UL
00352 
00353 /**
00354  * Parse retrieval protocol block fetch response
00355  *
00356  * @v raw               Raw data
00357  * @v raw_len           Length of raw data
00358  * @v digestsize        Digest size
00359  * @v blksize           Cipher block size
00360  * @v blk               Structure to fill in
00361  * @ret rc              Return status code
00362  */
00363 #define peerdist_msg_blk( raw, raw_len, digestsize, blksize, blk ) ( {  \
00364         assert ( sizeof ( (blk)->segment.id ) == (digestsize) );        \
00365         assert ( sizeof ( (blk)->block.data ) == 0 );                   \
00366         assert ( sizeof ( (blk)->vrf.data ) == 0 );                     \
00367         assert ( sizeof ( (blk)->iv.data ) == blksize );                \
00368         peerdist_msg_blk_untyped ( (raw), (raw_len), (digestsize),      \
00369                                    (blksize), blk );                    \
00370         } )
00371 
00372 extern int peerdist_msg_blk_untyped ( userptr_t raw, size_t raw_len,
00373                                       size_t digestsize, size_t blksize,
00374                                       void *out );
00375 
00376 #endif /* _IPXE_PCCRR_H */