summaryrefslogtreecommitdiff
path: root/lib9p/types.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib9p/types.c')
-rw-r--r--lib9p/types.c31
1 files changed, 25 insertions, 6 deletions
diff --git a/lib9p/types.c b/lib9p/types.c
index 18dcbfe..50ac1cf 100644
--- a/lib9p/types.c
+++ b/lib9p/types.c
@@ -384,6 +384,17 @@ static ALWAYS_INLINE bool validate_stat(struct _validate_ctx *ctx) {
|| ( (ctx->ctx->version==LIB9P_VER_9P2000_u) && validate_4(ctx) );
}
+static ALWAYS_INLINE bool validate_o(struct _validate_ctx *ctx) {
+ if (validate_1(ctx))
+ return true;
+ static const lib9p_o_t mask = 0b01010011;
+ lib9p_o_t val = decode_u8le(&ctx->net_bytes[ctx->net_offset-1]);
+ if (val & ~mask)
+ return lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "unknown bits in o bitfield: %#01"PRIx8,
+ val & ~mask);
+ return false;
+}
+
static FLATTEN bool validate_Tversion(struct _validate_ctx *ctx) {
return validate_4(ctx)
|| validate_s(ctx);
@@ -443,7 +454,7 @@ static FLATTEN bool validate_Rwalk(struct _validate_ctx *ctx) {
static FLATTEN bool validate_Topen(struct _validate_ctx *ctx) {
return validate_4(ctx)
- || validate_1(ctx);
+ || validate_o(ctx);
}
static FLATTEN bool validate_Ropen(struct _validate_ctx *ctx) {
@@ -455,7 +466,7 @@ static FLATTEN bool validate_Tcreate(struct _validate_ctx *ctx) {
return validate_4(ctx)
|| validate_s(ctx)
|| validate_4(ctx)
- || validate_1(ctx);
+ || validate_o(ctx);
}
static FLATTEN bool validate_Rcreate(struct _validate_ctx *ctx) {
@@ -616,6 +627,10 @@ static ALWAYS_INLINE void unmarshal_stat(struct _unmarshal_ctx *ctx, struct lib9
if ( (ctx->ctx->version==LIB9P_VER_9P2000_u) ) unmarshal_4(ctx, &out->file_last_modified_n_uid);
}
+static ALWAYS_INLINE void unmarshal_o(struct _unmarshal_ctx *ctx, lib9p_o_t *out) {
+ unmarshal_1(ctx, (uint8_t *)out);
+}
+
static FLATTEN void unmarshal_Tversion(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tversion *out) {
memset(out, 0, sizeof(*out));
unmarshal_4(ctx, &out->max_msg_size);
@@ -692,7 +707,7 @@ static FLATTEN void unmarshal_Rwalk(struct _unmarshal_ctx *ctx, struct lib9p_msg
static FLATTEN void unmarshal_Topen(struct _unmarshal_ctx *ctx, struct lib9p_msg_Topen *out) {
memset(out, 0, sizeof(*out));
unmarshal_4(ctx, &out->fid);
- unmarshal_1(ctx, &out->mode);
+ unmarshal_o(ctx, &out->mode);
}
static FLATTEN void unmarshal_Ropen(struct _unmarshal_ctx *ctx, struct lib9p_msg_Ropen *out) {
@@ -706,7 +721,7 @@ static FLATTEN void unmarshal_Tcreate(struct _unmarshal_ctx *ctx, struct lib9p_m
unmarshal_4(ctx, &out->fid);
unmarshal_s(ctx, &out->name);
unmarshal_4(ctx, &out->perm);
- unmarshal_1(ctx, &out->mode);
+ unmarshal_o(ctx, &out->mode);
}
static FLATTEN void unmarshal_Rcreate(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rcreate *out) {
@@ -908,6 +923,10 @@ static ALWAYS_INLINE bool marshal_stat(struct _marshal_ctx *ctx, struct lib9p_st
|| ( (ctx->ctx->version==LIB9P_VER_9P2000_u) && marshal_4(ctx, &val->file_last_modified_n_uid) );
}
+static ALWAYS_INLINE bool marshal_o(struct _marshal_ctx *ctx, lib9p_o_t *val) {
+ return marshal_1(ctx, (uint8_t *)val);
+}
+
static FLATTEN bool marshal_Tversion(struct _marshal_ctx *ctx, struct lib9p_msg_Tversion *val) {
return marshal_4(ctx, &val->max_msg_size)
|| marshal_s(ctx, &val->version);
@@ -977,7 +996,7 @@ static FLATTEN bool marshal_Rwalk(struct _marshal_ctx *ctx, struct lib9p_msg_Rwa
static FLATTEN bool marshal_Topen(struct _marshal_ctx *ctx, struct lib9p_msg_Topen *val) {
return marshal_4(ctx, &val->fid)
- || marshal_1(ctx, &val->mode);
+ || marshal_o(ctx, &val->mode);
}
static FLATTEN bool marshal_Ropen(struct _marshal_ctx *ctx, struct lib9p_msg_Ropen *val) {
@@ -989,7 +1008,7 @@ static FLATTEN bool marshal_Tcreate(struct _marshal_ctx *ctx, struct lib9p_msg_T
return marshal_4(ctx, &val->fid)
|| marshal_s(ctx, &val->name)
|| marshal_4(ctx, &val->perm)
- || marshal_1(ctx, &val->mode);
+ || marshal_o(ctx, &val->mode);
}
static FLATTEN bool marshal_Rcreate(struct _marshal_ctx *ctx, struct lib9p_msg_Rcreate *val) {