* Receive a control message */
| 257 | * Receive a control message |
| 258 | */ |
| 259 | static int |
| 260 | ng_mppc_rcvmsg(node_p node, item_p item, hook_p lasthook) |
| 261 | { |
| 262 | const priv_p priv = NG_NODE_PRIVATE(node); |
| 263 | struct ng_mesg *resp = NULL; |
| 264 | int error = 0; |
| 265 | struct ng_mesg *msg; |
| 266 | |
| 267 | NGI_GET_MSG(item, msg); |
| 268 | switch (msg->header.typecookie) { |
| 269 | case NGM_MPPC_COOKIE: |
| 270 | switch (msg->header.cmd) { |
| 271 | case NGM_MPPC_CONFIG_COMP: |
| 272 | case NGM_MPPC_CONFIG_DECOMP: |
| 273 | { |
| 274 | struct ng_mppc_config *const cfg |
| 275 | = (struct ng_mppc_config *)msg->data; |
| 276 | const int isComp = |
| 277 | msg->header.cmd == NGM_MPPC_CONFIG_COMP; |
| 278 | struct ng_mppc_dir *const d = isComp ? |
| 279 | &priv->xmit : &priv->recv; |
| 280 | |
| 281 | /* Check configuration */ |
| 282 | if (msg->header.arglen != sizeof(*cfg)) |
| 283 | ERROUT(EINVAL); |
| 284 | if (cfg->enable) { |
| 285 | if ((cfg->bits & ~MPPC_VALID_BITS) != 0) |
| 286 | ERROUT(EINVAL); |
| 287 | #ifndef NETGRAPH_MPPC_COMPRESSION |
| 288 | if ((cfg->bits & MPPC_BIT) != 0) |
| 289 | ERROUT(EPROTONOSUPPORT); |
| 290 | #endif |
| 291 | #ifndef NETGRAPH_MPPC_ENCRYPTION |
| 292 | if ((cfg->bits & MPPE_BITS) != 0) |
| 293 | ERROUT(EPROTONOSUPPORT); |
| 294 | #endif |
| 295 | } else |
| 296 | cfg->bits = 0; |
| 297 | |
| 298 | /* Save return address so we can send reset-req's */ |
| 299 | if (!isComp) |
| 300 | priv->ctrlnode = NGI_RETADDR(item); |
| 301 | |
| 302 | /* Configuration is OK, reset to it */ |
| 303 | d->cfg = *cfg; |
| 304 | |
| 305 | #ifdef NETGRAPH_MPPC_COMPRESSION |
| 306 | /* Initialize state buffers for compression */ |
| 307 | if (d->history != NULL) { |
| 308 | free(d->history, M_NETGRAPH_MPPC); |
| 309 | d->history = NULL; |
| 310 | } |
| 311 | if ((cfg->bits & MPPC_BIT) != 0) { |
| 312 | d->history = malloc(isComp ? |
| 313 | MPPC_SizeOfCompressionHistory() : |
| 314 | MPPC_SizeOfDecompressionHistory(), |
| 315 | M_NETGRAPH_MPPC, M_NOWAIT); |
| 316 | if (d->history == NULL) |
nothing calls this directly
no test coverage detected