36#include <sys/kernel.h>
37#include <sys/endian.h>
38#include <sys/malloc.h>
42#include <net/ethernet.h>
68#define ERROUT(x) { error = (x); goto done; }
72 const u_char *start,
const u_char *buf)
225 if (privp->conf == NULL)
234 bcopy(privp->conf, resp->
data,
239 for (i = 0; i < conf->
count; i++) {
265 for (i = 0; i < conf->
count; i++) {
292 free(privp->conf, M_NETGRAPH);
294 privp->conf = newconf;
321 *((uint8_t *) resp->
data) = privp->dlt;
329 switch (*(uint8_t *) msg->
data)
333 privp->dlt = *(uint8_t *) msg->
data;
356 int i, offset, patched = 0;
359 for (i = 0; i < privp->conf->count; i++) {
360 offset = global_offset + privp->conf->ops[i].offset;
362 if (offset + privp->conf->ops[i].length > m->m_pkthdr.len)
367 m_copydata(m, offset, privp->conf->ops[i].length, (caddr_t) &val);
369 switch (privp->conf->ops[i].length)
372 switch (privp->conf->ops[i].mode)
375 val.v1 = privp->conf->ops[i].val.v1;
378 val.v1 += privp->conf->ops[i].val.v1;
381 val.v1 -= privp->conf->ops[i].val.v1;
384 val.v1 *= privp->conf->ops[i].val.v1;
387 val.v1 /= privp->conf->ops[i].val.v1;
390 *((int8_t *) &val) = - *((int8_t *) &val);
393 val.v1 &= privp->conf->ops[i].val.v1;
396 val.v1 |= privp->conf->ops[i].val.v1;
399 val.v1 ^= privp->conf->ops[i].val.v1;
402 val.v1 <<= privp->conf->ops[i].val.v1;
405 val.v1 >>= privp->conf->ops[i].val.v1;
411 val.v2 = ntohs(val.v2);
413 switch (privp->conf->ops[i].mode)
416 val.v2 = privp->conf->ops[i].val.v2;
419 val.v2 += privp->conf->ops[i].val.v2;
422 val.v2 -= privp->conf->ops[i].val.v2;
425 val.v2 *= privp->conf->ops[i].val.v2;
428 val.v2 /= privp->conf->ops[i].val.v2;
431 *((int16_t *) &val) = - *((int16_t *) &val);
434 val.v2 &= privp->conf->ops[i].val.v2;
437 val.v2 |= privp->conf->ops[i].val.v2;
440 val.v2 ^= privp->conf->ops[i].val.v2;
443 val.v2 <<= privp->conf->ops[i].val.v2;
446 val.v2 >>= privp->conf->ops[i].val.v2;
450 val.v2 = htons(val.v2);
455 val.v4 = ntohl(val.v4);
457 switch (privp->conf->ops[i].mode)
460 val.v4 = privp->conf->ops[i].val.v4;
463 val.v4 += privp->conf->ops[i].val.v4;
466 val.v4 -= privp->conf->ops[i].val.v4;
469 val.v4 *= privp->conf->ops[i].val.v4;
472 val.v4 /= privp->conf->ops[i].val.v4;
475 *((int32_t *) &val) = - *((int32_t *) &val);
478 val.v4 &= privp->conf->ops[i].val.v4;
481 val.v4 |= privp->conf->ops[i].val.v4;
484 val.v4 ^= privp->conf->ops[i].val.v4;
487 val.v4 <<= privp->conf->ops[i].val.v4;
490 val.v4 >>= privp->conf->ops[i].val.v4;
494 val.v4 = htonl(val.v4);
499 val.v8 = be64toh(val.v8);
501 switch (privp->conf->ops[i].mode)
504 val.v8 = privp->conf->ops[i].val.v8;
507 val.v8 += privp->conf->ops[i].val.v8;
510 val.v8 -= privp->conf->ops[i].val.v8;
513 val.v8 *= privp->conf->ops[i].val.v8;
516 val.v8 /= privp->conf->ops[i].val.v8;
519 *((int64_t *) &val) = - *((int64_t *) &val);
522 val.v8 &= privp->conf->ops[i].val.v8;
525 val.v8 |= privp->conf->ops[i].val.v8;
528 val.v8 ^= privp->conf->ops[i].val.v8;
531 val.v8 <<= privp->conf->ops[i].val.v8;
534 val.v8 >>= privp->conf->ops[i].val.v8;
538 val.v8 = htobe64(val.v8);
543 m_copyback(m, offset, privp->conf->ops[i].length, (caddr_t) &val);
548 privp->stats.patched++;
564#define PULLUP_CHECK(mbuf, length) do { \
565 pullup_len += length; \
566 if (((mbuf)->m_pkthdr.len < pullup_len) || \
567 (pullup_len > MHLEN)) { \
571 if ((mbuf)->m_len < pullup_len && \
572 (((mbuf) = m_pullup((mbuf), pullup_len)) == NULL)) { \
578 if (
priv->conf && hook ==
priv->in &&
579 m && (m->m_flags & M_PKTHDR)) {
580 m = m_unshare(m, M_NOWAIT);
585 if (
priv->conf->relative_offset) {
586 struct ether_header *eh;
594 eh = mtod(m,
struct ether_header *);
595 etype = ntohs(eh->ether_type);
626 m->m_pkthdr.csum_flags |=
priv->conf->csum_flags;
634 if (hook ==
priv->in) {
637 }
else if (hook ==
priv->out &&
priv->in) {
682 if (hook ==
priv->in) {
686 if (hook ==
priv->out) {
#define NG_HOOK_NODE(hook)
int ng_rcvmsg_t(node_p node, item_p item, hook_p lasthook)
int ng_disconnect_t(hook_p hook)
#define NG_NODE_SET_PRIVATE(node, val)
#define NG_RESPOND_MSG(error, here, item, resp)
#define NG_NODE_IS_VALID(node)
#define NG_NODE_UNREF(node)
int ng_rmnode_self(node_p here)
#define NG_FWD_NEW_DATA(error, item, hook, m)
int ng_rcvdata_t(hook_p hook, item_p item)
int ng_shutdown_t(node_p node)
#define NG_FREE_ITEM(item)
int ng_constructor_t(node_p node)
#define NG_NODE_NUMHOOKS(node)
#define NGI_GET_MSG(i, m)
#define NG_NODE_PRIVATE(node)
int ng_newhook_t(node_p node, hook_p hook, const char *name)
#define NG_MKRESPONSE(rsp, msg, len, how)
const struct ng_parse_type ng_parse_array_type
const struct ng_parse_type ng_parse_struct_type
const struct ng_parse_type ng_parse_uint8_type
static ng_newhook_t ng_patch_newhook
static const struct ng_parse_struct_field ng_patch_op_type_fields[]
static void do_patch(priv_p privp, struct mbuf *m, int global_offset)
static int ng_patch_config_getlen(const struct ng_parse_type *type, const u_char *start, const u_char *buf)
static ng_rcvdata_t ng_patch_rcvdata
static ng_shutdown_t ng_patch_shutdown
static const struct ng_parse_type ng_patch_op_type
static struct ng_type typestruct
#define PULLUP_CHECK(mbuf, length)
static ng_constructor_t ng_patch_constructor
static const struct ng_parse_struct_field ng_patch_stats_fields[]
NETGRAPH_INIT(patch, &typestruct)
static const struct ng_parse_struct_field ng_patch_config_type_fields[]
static const struct ng_parse_type ng_patch_ops_array_type
static const struct ng_parse_array_info ng_patch_ops_array_info
static ng_disconnect_t ng_patch_disconnect
static const struct ng_cmdlist ng_patch_cmdlist[]
static const struct ng_parse_type ng_patch_stats_type
static ng_rcvmsg_t ng_patch_rcvmsg
struct ng_patch_priv * priv_p
static const struct ng_parse_type ng_patch_config_type
#define NG_PATCH_CONF_SIZE(count)
#define NG_PATCH_CSUM_IPV4
#define NG_PATCH_STATS_TYPE
#define NG_PATCH_CSUM_IPV6
#define NG_PATCH_CONFIG_TYPE
#define NG_PATCH_HOOK_OUT
#define NG_PATCH_NODE_TYPE
struct ng_mesg::ng_msghdr header
union ng_patch_op_val val
struct ng_patch_config * conf