003 File Manager
Current Path:
/usr/src/sys/netgraph
usr
/
src
/
sys
/
netgraph
/
📁
..
📄
NOTES
(3.63 KB)
📁
atm
📁
bluetooth
📁
netflow
📄
netgraph.h
(41.17 KB)
📄
ng_UI.c
(6.29 KB)
📄
ng_UI.h
(2.36 KB)
📄
ng_async.c
(16.51 KB)
📄
ng_async.h
(4.05 KB)
📄
ng_atmllc.c
(7.25 KB)
📄
ng_atmllc.h
(1.85 KB)
📄
ng_base.c
(100.62 KB)
📄
ng_bpf.c
(14.66 KB)
📄
ng_bpf.h
(3.97 KB)
📄
ng_bridge.c
(29.37 KB)
📄
ng_bridge.h
(7.58 KB)
📄
ng_car.c
(19.62 KB)
📄
ng_car.h
(4.6 KB)
📄
ng_checksum.c
(15.85 KB)
📄
ng_checksum.h
(2.63 KB)
📄
ng_cisco.c
(15.47 KB)
📄
ng_cisco.h
(3.39 KB)
📄
ng_deflate.c
(17.09 KB)
📄
ng_deflate.h
(2.85 KB)
📄
ng_device.c
(10.65 KB)
📄
ng_device.h
(1.74 KB)
📄
ng_echo.c
(3.52 KB)
📄
ng_echo.h
(2.28 KB)
📄
ng_eiface.c
(16.31 KB)
📄
ng_eiface.h
(2.09 KB)
📄
ng_etf.c
(12.84 KB)
📄
ng_etf.h
(3.05 KB)
📄
ng_ether.c
(22.26 KB)
📄
ng_ether.h
(3.22 KB)
📄
ng_ether_echo.c
(4.17 KB)
📄
ng_ether_echo.h
(2.32 KB)
📄
ng_frame_relay.c
(13.21 KB)
📄
ng_frame_relay.h
(2.51 KB)
📄
ng_gif.c
(15.86 KB)
📄
ng_gif.h
(4.04 KB)
📄
ng_gif_demux.c
(10.83 KB)
📄
ng_gif_demux.h
(2.05 KB)
📄
ng_hole.c
(5.85 KB)
📄
ng_hole.h
(2.69 KB)
📄
ng_hub.c
(4.33 KB)
📄
ng_hub.h
(1.68 KB)
📄
ng_iface.c
(19.58 KB)
📄
ng_iface.h
(2.68 KB)
📄
ng_ip_input.c
(4.97 KB)
📄
ng_ip_input.h
(3.78 KB)
📄
ng_ipfw.c
(8.29 KB)
📄
ng_ipfw.h
(1.54 KB)
📄
ng_ksocket.c
(33.9 KB)
📄
ng_ksocket.h
(3.86 KB)
📄
ng_l2tp.c
(40.16 KB)
📄
ng_l2tp.h
(8.12 KB)
📄
ng_lmi.c
(28.15 KB)
📄
ng_lmi.h
(3.2 KB)
📄
ng_macfilter.c
(24.45 KB)
📄
ng_macfilter.h
(5.7 KB)
📄
ng_message.h
(14.69 KB)
📄
ng_mppc.c
(23.88 KB)
📄
ng_mppc.h
(3.29 KB)
📄
ng_nat.c
(23.43 KB)
📄
ng_nat.h
(6.87 KB)
📄
ng_one2many.c
(15.88 KB)
📄
ng_one2many.h
(4.56 KB)
📄
ng_parse.c
(43.85 KB)
📄
ng_parse.h
(18.49 KB)
📄
ng_patch.c
(15.54 KB)
📄
ng_patch.h
(3.64 KB)
📄
ng_pipe.c
(26.97 KB)
📄
ng_pipe.h
(5.56 KB)
📄
ng_ppp.c
(72.27 KB)
📄
ng_ppp.h
(9.77 KB)
📄
ng_pppoe.c
(58.34 KB)
📄
ng_pppoe.h
(9.64 KB)
📄
ng_pptpgre.c
(36.05 KB)
📄
ng_pptpgre.h
(6.04 KB)
📄
ng_pred1.c
(18.02 KB)
📄
ng_pred1.h
(2.73 KB)
📄
ng_rfc1490.c
(13.33 KB)
📄
ng_rfc1490.h
(2.62 KB)
📄
ng_sample.c
(15.14 KB)
📄
ng_sample.h
(3.53 KB)
📄
ng_socket.c
(29.91 KB)
📄
ng_socket.h
(2.73 KB)
📄
ng_socketvar.h
(2.51 KB)
📄
ng_source.c
(21.72 KB)
📄
ng_source.h
(4.96 KB)
📄
ng_split.c
(4.54 KB)
📄
ng_split.h
(1.84 KB)
📄
ng_sppp.c
(9.39 KB)
📄
ng_sppp.h
(1.03 KB)
📄
ng_tag.c
(19.05 KB)
📄
ng_tag.h
(4.55 KB)
📄
ng_tcpmss.c
(10.63 KB)
📄
ng_tcpmss.h
(2.73 KB)
📄
ng_tee.c
(10.61 KB)
📄
ng_tee.h
(3.51 KB)
📄
ng_tty.c
(11.96 KB)
📄
ng_tty.h
(2.49 KB)
📄
ng_vjc.c
(15.66 KB)
📄
ng_vjc.h
(3.5 KB)
📄
ng_vlan.c
(17.61 KB)
📄
ng_vlan.h
(3.47 KB)
Editing: ng_patch.c
/*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 2010 Maxim Ignatenko <gelraen.ua@gmail.com> * Copyright (c) 2015 Dmitry Vagin <daemon.hammer@ya.ru> * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> #include <sys/endian.h> #include <sys/malloc.h> #include <sys/mbuf.h> #include <net/bpf.h> #include <net/ethernet.h> #include <netgraph/ng_message.h> #include <netgraph/ng_parse.h> #include <netgraph/netgraph.h> #include <netgraph/ng_patch.h> /* private data */ struct ng_patch_priv { hook_p in; hook_p out; uint8_t dlt; /* DLT_XXX from bpf.h */ struct ng_patch_stats stats; struct ng_patch_config *conf; }; typedef struct ng_patch_priv *priv_p; /* Netgraph methods */ static ng_constructor_t ng_patch_constructor; static ng_rcvmsg_t ng_patch_rcvmsg; static ng_shutdown_t ng_patch_shutdown; static ng_newhook_t ng_patch_newhook; static ng_rcvdata_t ng_patch_rcvdata; static ng_disconnect_t ng_patch_disconnect; #define ERROUT(x) { error = (x); goto done; } static int ng_patch_config_getlen(const struct ng_parse_type *type, const u_char *start, const u_char *buf) { const struct ng_patch_config *conf; conf = (const struct ng_patch_config *)(buf - offsetof(struct ng_patch_config, ops)); return (conf->count); } static const struct ng_parse_struct_field ng_patch_op_type_fields[] = NG_PATCH_OP_TYPE; static const struct ng_parse_type ng_patch_op_type = { &ng_parse_struct_type, &ng_patch_op_type_fields }; static const struct ng_parse_array_info ng_patch_ops_array_info = { &ng_patch_op_type, &ng_patch_config_getlen }; static const struct ng_parse_type ng_patch_ops_array_type = { &ng_parse_array_type, &ng_patch_ops_array_info }; static const struct ng_parse_struct_field ng_patch_config_type_fields[] = NG_PATCH_CONFIG_TYPE; static const struct ng_parse_type ng_patch_config_type = { &ng_parse_struct_type, &ng_patch_config_type_fields }; static const struct ng_parse_struct_field ng_patch_stats_fields[] = NG_PATCH_STATS_TYPE; static const struct ng_parse_type ng_patch_stats_type = { &ng_parse_struct_type, &ng_patch_stats_fields }; static const struct ng_cmdlist ng_patch_cmdlist[] = { { NGM_PATCH_COOKIE, NGM_PATCH_GETDLT, "getdlt", NULL, &ng_parse_uint8_type }, { NGM_PATCH_COOKIE, NGM_PATCH_SETDLT, "setdlt", &ng_parse_uint8_type, NULL }, { NGM_PATCH_COOKIE, NGM_PATCH_GETCONFIG, "getconfig", NULL, &ng_patch_config_type }, { NGM_PATCH_COOKIE, NGM_PATCH_SETCONFIG, "setconfig", &ng_patch_config_type, NULL }, { NGM_PATCH_COOKIE, NGM_PATCH_GET_STATS, "getstats", NULL, &ng_patch_stats_type }, { NGM_PATCH_COOKIE, NGM_PATCH_CLR_STATS, "clrstats", NULL, NULL }, { NGM_PATCH_COOKIE, NGM_PATCH_GETCLR_STATS, "getclrstats", NULL, &ng_patch_stats_type }, { 0 } }; static struct ng_type typestruct = { .version = NG_ABI_VERSION, .name = NG_PATCH_NODE_TYPE, .constructor = ng_patch_constructor, .rcvmsg = ng_patch_rcvmsg, .shutdown = ng_patch_shutdown, .newhook = ng_patch_newhook, .rcvdata = ng_patch_rcvdata, .disconnect = ng_patch_disconnect, .cmdlist = ng_patch_cmdlist, }; NETGRAPH_INIT(patch, &typestruct); static int ng_patch_constructor(node_p node) { priv_p privdata; privdata = malloc(sizeof(*privdata), M_NETGRAPH, M_WAITOK | M_ZERO); privdata->dlt = DLT_RAW; NG_NODE_SET_PRIVATE(node, privdata); return (0); } static int ng_patch_newhook(node_p node, hook_p hook, const char *name) { const priv_p privp = NG_NODE_PRIVATE(node); if (strncmp(name, NG_PATCH_HOOK_IN, strlen(NG_PATCH_HOOK_IN)) == 0) { privp->in = hook; } else if (strncmp(name, NG_PATCH_HOOK_OUT, strlen(NG_PATCH_HOOK_OUT)) == 0) { privp->out = hook; } else return (EINVAL); return (0); } static int ng_patch_rcvmsg(node_p node, item_p item, hook_p lasthook) { const priv_p privp = NG_NODE_PRIVATE(node); struct ng_patch_config *conf, *newconf; struct ng_mesg *msg; struct ng_mesg *resp = NULL; int i, error = 0; NGI_GET_MSG(item, msg); if (msg->header.typecookie != NGM_PATCH_COOKIE) ERROUT(EINVAL); switch (msg->header.cmd) { case NGM_PATCH_GETCONFIG: if (privp->conf == NULL) ERROUT(0); NG_MKRESPONSE(resp, msg, NG_PATCH_CONF_SIZE(privp->conf->count), M_WAITOK); if (resp == NULL) ERROUT(ENOMEM); bcopy(privp->conf, resp->data, NG_PATCH_CONF_SIZE(privp->conf->count)); conf = (struct ng_patch_config *) resp->data; for (i = 0; i < conf->count; i++) { switch (conf->ops[i].length) { case 1: conf->ops[i].val.v8 = conf->ops[i].val.v1; break; case 2: conf->ops[i].val.v8 = conf->ops[i].val.v2; break; case 4: conf->ops[i].val.v8 = conf->ops[i].val.v4; break; case 8: break; } } break; case NGM_PATCH_SETCONFIG: conf = (struct ng_patch_config *) msg->data; if (msg->header.arglen < sizeof(struct ng_patch_config) || msg->header.arglen < NG_PATCH_CONF_SIZE(conf->count)) ERROUT(EINVAL); for (i = 0; i < conf->count; i++) { switch (conf->ops[i].length) { case 1: conf->ops[i].val.v1 = (uint8_t) conf->ops[i].val.v8; break; case 2: conf->ops[i].val.v2 = (uint16_t) conf->ops[i].val.v8; break; case 4: conf->ops[i].val.v4 = (uint32_t) conf->ops[i].val.v8; break; case 8: break; default: ERROUT(EINVAL); } } conf->csum_flags &= NG_PATCH_CSUM_IPV4|NG_PATCH_CSUM_IPV6; conf->relative_offset = !!conf->relative_offset; newconf = malloc(NG_PATCH_CONF_SIZE(conf->count), M_NETGRAPH, M_WAITOK | M_ZERO); bcopy(conf, newconf, NG_PATCH_CONF_SIZE(conf->count)); if (privp->conf) free(privp->conf, M_NETGRAPH); privp->conf = newconf; break; case NGM_PATCH_GET_STATS: case NGM_PATCH_CLR_STATS: case NGM_PATCH_GETCLR_STATS: if (msg->header.cmd != NGM_PATCH_CLR_STATS) { NG_MKRESPONSE(resp, msg, sizeof(struct ng_patch_stats), M_WAITOK); if (resp == NULL) ERROUT(ENOMEM); bcopy(&(privp->stats), resp->data, sizeof(struct ng_patch_stats)); } if (msg->header.cmd != NGM_PATCH_GET_STATS) bzero(&(privp->stats), sizeof(struct ng_patch_stats)); break; case NGM_PATCH_GETDLT: NG_MKRESPONSE(resp, msg, sizeof(uint8_t), M_WAITOK); if (resp == NULL) ERROUT(ENOMEM); *((uint8_t *) resp->data) = privp->dlt; break; case NGM_PATCH_SETDLT: if (msg->header.arglen != sizeof(uint8_t)) ERROUT(EINVAL); switch (*(uint8_t *) msg->data) { case DLT_EN10MB: case DLT_RAW: privp->dlt = *(uint8_t *) msg->data; break; default: ERROUT(EINVAL); } break; default: ERROUT(EINVAL); } done: NG_RESPOND_MSG(error, node, item, resp); NG_FREE_MSG(msg); return (error); } static void do_patch(priv_p privp, struct mbuf *m, int global_offset) { int i, offset, patched = 0; union ng_patch_op_val val; for (i = 0; i < privp->conf->count; i++) { offset = global_offset + privp->conf->ops[i].offset; if (offset + privp->conf->ops[i].length > m->m_pkthdr.len) continue; /* for "=" operation we don't need to copy data from mbuf */ if (privp->conf->ops[i].mode != NG_PATCH_MODE_SET) m_copydata(m, offset, privp->conf->ops[i].length, (caddr_t) &val); switch (privp->conf->ops[i].length) { case 1: switch (privp->conf->ops[i].mode) { case NG_PATCH_MODE_SET: val.v1 = privp->conf->ops[i].val.v1; break; case NG_PATCH_MODE_ADD: val.v1 += privp->conf->ops[i].val.v1; break; case NG_PATCH_MODE_SUB: val.v1 -= privp->conf->ops[i].val.v1; break; case NG_PATCH_MODE_MUL: val.v1 *= privp->conf->ops[i].val.v1; break; case NG_PATCH_MODE_DIV: val.v1 /= privp->conf->ops[i].val.v1; break; case NG_PATCH_MODE_NEG: *((int8_t *) &val) = - *((int8_t *) &val); break; case NG_PATCH_MODE_AND: val.v1 &= privp->conf->ops[i].val.v1; break; case NG_PATCH_MODE_OR: val.v1 |= privp->conf->ops[i].val.v1; break; case NG_PATCH_MODE_XOR: val.v1 ^= privp->conf->ops[i].val.v1; break; case NG_PATCH_MODE_SHL: val.v1 <<= privp->conf->ops[i].val.v1; break; case NG_PATCH_MODE_SHR: val.v1 >>= privp->conf->ops[i].val.v1; break; } break; case 2: val.v2 = ntohs(val.v2); switch (privp->conf->ops[i].mode) { case NG_PATCH_MODE_SET: val.v2 = privp->conf->ops[i].val.v2; break; case NG_PATCH_MODE_ADD: val.v2 += privp->conf->ops[i].val.v2; break; case NG_PATCH_MODE_SUB: val.v2 -= privp->conf->ops[i].val.v2; break; case NG_PATCH_MODE_MUL: val.v2 *= privp->conf->ops[i].val.v2; break; case NG_PATCH_MODE_DIV: val.v2 /= privp->conf->ops[i].val.v2; break; case NG_PATCH_MODE_NEG: *((int16_t *) &val) = - *((int16_t *) &val); break; case NG_PATCH_MODE_AND: val.v2 &= privp->conf->ops[i].val.v2; break; case NG_PATCH_MODE_OR: val.v2 |= privp->conf->ops[i].val.v2; break; case NG_PATCH_MODE_XOR: val.v2 ^= privp->conf->ops[i].val.v2; break; case NG_PATCH_MODE_SHL: val.v2 <<= privp->conf->ops[i].val.v2; break; case NG_PATCH_MODE_SHR: val.v2 >>= privp->conf->ops[i].val.v2; break; } val.v2 = htons(val.v2); break; case 4: val.v4 = ntohl(val.v4); switch (privp->conf->ops[i].mode) { case NG_PATCH_MODE_SET: val.v4 = privp->conf->ops[i].val.v4; break; case NG_PATCH_MODE_ADD: val.v4 += privp->conf->ops[i].val.v4; break; case NG_PATCH_MODE_SUB: val.v4 -= privp->conf->ops[i].val.v4; break; case NG_PATCH_MODE_MUL: val.v4 *= privp->conf->ops[i].val.v4; break; case NG_PATCH_MODE_DIV: val.v4 /= privp->conf->ops[i].val.v4; break; case NG_PATCH_MODE_NEG: *((int32_t *) &val) = - *((int32_t *) &val); break; case NG_PATCH_MODE_AND: val.v4 &= privp->conf->ops[i].val.v4; break; case NG_PATCH_MODE_OR: val.v4 |= privp->conf->ops[i].val.v4; break; case NG_PATCH_MODE_XOR: val.v4 ^= privp->conf->ops[i].val.v4; break; case NG_PATCH_MODE_SHL: val.v4 <<= privp->conf->ops[i].val.v4; break; case NG_PATCH_MODE_SHR: val.v4 >>= privp->conf->ops[i].val.v4; break; } val.v4 = htonl(val.v4); break; case 8: val.v8 = be64toh(val.v8); switch (privp->conf->ops[i].mode) { case NG_PATCH_MODE_SET: val.v8 = privp->conf->ops[i].val.v8; break; case NG_PATCH_MODE_ADD: val.v8 += privp->conf->ops[i].val.v8; break; case NG_PATCH_MODE_SUB: val.v8 -= privp->conf->ops[i].val.v8; break; case NG_PATCH_MODE_MUL: val.v8 *= privp->conf->ops[i].val.v8; break; case NG_PATCH_MODE_DIV: val.v8 /= privp->conf->ops[i].val.v8; break; case NG_PATCH_MODE_NEG: *((int64_t *) &val) = - *((int64_t *) &val); break; case NG_PATCH_MODE_AND: val.v8 &= privp->conf->ops[i].val.v8; break; case NG_PATCH_MODE_OR: val.v8 |= privp->conf->ops[i].val.v8; break; case NG_PATCH_MODE_XOR: val.v8 ^= privp->conf->ops[i].val.v8; break; case NG_PATCH_MODE_SHL: val.v8 <<= privp->conf->ops[i].val.v8; break; case NG_PATCH_MODE_SHR: val.v8 >>= privp->conf->ops[i].val.v8; break; } val.v8 = htobe64(val.v8); break; } m_copyback(m, offset, privp->conf->ops[i].length, (caddr_t) &val); patched = 1; } if (patched) privp->stats.patched++; } static int ng_patch_rcvdata(hook_p hook, item_p item) { const priv_p priv = NG_NODE_PRIVATE(NG_HOOK_NODE(hook)); struct mbuf *m; hook_p out; int pullup_len = 0; int error = 0; priv->stats.received++; NGI_GET_M(item, m); #define PULLUP_CHECK(mbuf, length) do { \ pullup_len += length; \ if (((mbuf)->m_pkthdr.len < pullup_len) || \ (pullup_len > MHLEN)) { \ error = EINVAL; \ goto bypass; \ } \ if ((mbuf)->m_len < pullup_len && \ (((mbuf) = m_pullup((mbuf), pullup_len)) == NULL)) { \ error = ENOBUFS; \ goto drop; \ } \ } while (0) if (priv->conf && hook == priv->in && m && (m->m_flags & M_PKTHDR)) { m = m_unshare(m, M_NOWAIT); if (m == NULL) ERROUT(ENOMEM); if (priv->conf->relative_offset) { struct ether_header *eh; struct ng_patch_vlan_header *vh; uint16_t etype; switch (priv->dlt) { case DLT_EN10MB: PULLUP_CHECK(m, sizeof(struct ether_header)); eh = mtod(m, struct ether_header *); etype = ntohs(eh->ether_type); for (;;) { /* QinQ support */ switch (etype) { case 0x8100: case 0x88A8: case 0x9100: PULLUP_CHECK(m, sizeof(struct ng_patch_vlan_header)); vh = (struct ng_patch_vlan_header *) mtodo(m, pullup_len - sizeof(struct ng_patch_vlan_header)); etype = ntohs(vh->etype); break; default: goto loopend; } } loopend: break; case DLT_RAW: break; default: ERROUT(EINVAL); } } do_patch(priv, m, pullup_len); m->m_pkthdr.csum_flags |= priv->conf->csum_flags; } #undef PULLUP_CHECK bypass: out = NULL; if (hook == priv->in) { /* return frames on 'in' hook if 'out' not connected */ out = priv->out ? priv->out : priv->in; } else if (hook == priv->out && priv->in) { /* pass frames on 'out' hook if 'in' connected */ out = priv->in; } if (out == NULL) ERROUT(0); NG_FWD_NEW_DATA(error, item, out, m); return (error); done: drop: NG_FREE_ITEM(item); NG_FREE_M(m); priv->stats.dropped++; return (error); } static int ng_patch_shutdown(node_p node) { const priv_p privdata = NG_NODE_PRIVATE(node); NG_NODE_SET_PRIVATE(node, NULL); NG_NODE_UNREF(node); if (privdata->conf != NULL) free(privdata->conf, M_NETGRAPH); free(privdata, M_NETGRAPH); return (0); } static int ng_patch_disconnect(hook_p hook) { priv_p priv; priv = NG_NODE_PRIVATE(NG_HOOK_NODE(hook)); if (hook == priv->in) { priv->in = NULL; } if (hook == priv->out) { priv->out = NULL; } if (NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0 && NG_NODE_IS_VALID(NG_HOOK_NODE(hook))) /* already shutting down? */ ng_rmnode_self(NG_HOOK_NODE(hook)); return (0); }
Upload File
Create Folder