4 #include <sys/socket.h>
5 #include <linux/rtnetlink.h>
10 int pack_control(uint8_t *data
, int len
, uint8_t type
, int argc
, char *argv
[])
12 struct nsctl_packet pkt
;
13 struct nsctl_args arg
;
15 int sz
= (p
- (char *) &pkt
);
17 if (len
> sizeof(pkt
))
21 argc
= 0xff; // paranoia
23 pkt
.magic
= ntohs(NSCTL_MAGIC
);
32 if (s
> sizeof(arg
.value
))
33 s
= sizeof(arg
.value
); // silently truncate
39 return -1; // overflow
42 memcpy(arg
.value
, a
, arg
.len
);
50 * terminate: this is both a sanity check and additionally
51 * ensures that there's a spare byte in the packet to null
52 * terminate the last argument when unpacking (see unpack_control)
54 if (sz
+ sizeof(arg
.len
) > len
)
55 return -1; // overflow
58 memcpy(p
, &arg
.len
, sizeof(arg
.len
));
60 sz
+= sizeof(arg
.len
);
61 memcpy(data
, &pkt
, sz
);
66 int unpack_control(struct nsctl
*control
, uint8_t *data
, int len
)
68 struct nsctl_packet pkt
;
70 int sz
= (p
- (char *) &pkt
);
74 return NSCTL_ERR_SHORT
;
76 if (len
> sizeof(pkt
))
77 return NSCTL_ERR_LONG
;
79 memcpy(&pkt
, data
, len
);
80 if (ntohs(pkt
.magic
) != NSCTL_MAGIC
)
81 return NSCTL_ERR_MAGIC
;
86 case NSCTL_REQ_UNLOAD
:
88 case NSCTL_REQ_CONTROL
:
91 control
->type
= pkt
.type
;
95 return NSCTL_ERR_TYPE
;
98 control
->argc
= pkt
.argc
;
99 for (i
= 0; i
<= control
->argc
; i
++)
104 return NSCTL_ERR_SHORT
;
107 *p
++ = 0; // null terminate previous arg
110 if (i
< control
->argc
)
113 return NSCTL_ERR_SHORT
;
115 control
->argv
[i
] = p
;
121 /* check for terminator */
123 return NSCTL_ERR_SHORT
;
128 return NSCTL_ERR_LONG
; // trailing cr*p
130 return control
->type
;
133 void dump_control(struct nsctl
*control
, FILE *stream
)
135 char *type
= "*unknown*";
140 switch (control
->type
)
142 case NSCTL_REQ_LOAD
: type
= "NSCTL_REQ_LOAD"; break;
143 case NSCTL_REQ_UNLOAD
: type
= "NSCTL_REQ_UNLOAD"; break;
144 case NSCTL_REQ_HELP
: type
= "NSCTL_REQ_HELP"; break;
145 case NSCTL_REQ_CONTROL
: type
= "NSCTL_REQ_CONTROL"; break;
146 case NSCTL_RES_OK
: type
= "NSCTL_RES_OK"; break;
147 case NSCTL_RES_ERR
: type
= "NSCTL_RES_ERR"; break;
150 fprintf(stream
, "Control packet:\n");
151 fprintf(stream
, " Type: %d (%s)\n", (int) control
->type
, type
);
152 fprintf(stream
, " Args: %d", (int) control
->argc
);
156 fprintf(stream
, " (\"");
157 for (i
= 0; i
< control
->argc
; i
++)
158 fprintf(stream
, "%s%s", i
? "\", \"" : "", control
->argv
[i
]);
160 fprintf(stream
, "\")");
163 fprintf(stream
, "\n\n");