4 #include <linux/rtnetlink.h>
5 #include <netinet/ip6.h>
11 int pack_control(uint8_t *data
, int len
, uint8_t type
, int argc
, char *argv
[])
13 struct nsctl_packet pkt
;
14 struct nsctl_args arg
;
16 int sz
= (p
- (char *) &pkt
);
18 if (len
> sizeof(pkt
))
22 argc
= 0xff; // paranoia
24 pkt
.magic
= ntohs(NSCTL_MAGIC
);
33 if (s
> sizeof(arg
.value
))
34 s
= sizeof(arg
.value
); // silently truncate
40 return -1; // overflow
43 memcpy(arg
.value
, a
, arg
.len
);
51 * terminate: this is both a sanity check and additionally
52 * ensures that there's a spare byte in the packet to null
53 * terminate the last argument when unpacking (see unpack_control)
55 if (sz
+ sizeof(arg
.len
) > len
)
56 return -1; // overflow
59 memcpy(p
, &arg
.len
, sizeof(arg
.len
));
61 sz
+= sizeof(arg
.len
);
62 memcpy(data
, &pkt
, sz
);
67 int unpack_control(struct nsctl
*control
, uint8_t *data
, int len
)
69 struct nsctl_packet pkt
;
71 int sz
= (p
- (char *) &pkt
);
75 return NSCTL_ERR_SHORT
;
77 if (len
> sizeof(pkt
))
78 return NSCTL_ERR_LONG
;
80 memcpy(&pkt
, data
, len
);
81 if (ntohs(pkt
.magic
) != NSCTL_MAGIC
)
82 return NSCTL_ERR_MAGIC
;
87 case NSCTL_REQ_UNLOAD
:
89 case NSCTL_REQ_CONTROL
:
92 control
->type
= pkt
.type
;
96 return NSCTL_ERR_TYPE
;
99 control
->argc
= pkt
.argc
;
100 for (i
= 0; i
<= control
->argc
; i
++)
105 return NSCTL_ERR_SHORT
;
108 *p
++ = 0; // null terminate previous arg
111 if (i
< control
->argc
)
114 return NSCTL_ERR_SHORT
;
116 control
->argv
[i
] = p
;
122 /* check for terminator */
124 return NSCTL_ERR_SHORT
;
129 return NSCTL_ERR_LONG
; // trailing cr*p
131 return control
->type
;
134 void dump_control(struct nsctl
*control
, FILE *stream
)
136 char *type
= "*unknown*";
141 switch (control
->type
)
143 case NSCTL_REQ_LOAD
: type
= "NSCTL_REQ_LOAD"; break;
144 case NSCTL_REQ_UNLOAD
: type
= "NSCTL_REQ_UNLOAD"; break;
145 case NSCTL_REQ_HELP
: type
= "NSCTL_REQ_HELP"; break;
146 case NSCTL_REQ_CONTROL
: type
= "NSCTL_REQ_CONTROL"; break;
147 case NSCTL_RES_OK
: type
= "NSCTL_RES_OK"; break;
148 case NSCTL_RES_ERR
: type
= "NSCTL_RES_ERR"; break;
151 fprintf(stream
, "Control packet:\n");
152 fprintf(stream
, " Type: %d (%s)\n", (int) control
->type
, type
);
153 fprintf(stream
, " Args: %d", (int) control
->argc
);
157 fprintf(stream
, " (\"");
158 for (i
= 0; i
< control
->argc
; i
++)
159 fprintf(stream
, "%s%s", i
? "\", \"" : "", control
->argv
[i
]);
161 fprintf(stream
, "\")");
164 fprintf(stream
, "\n\n");