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_tcpmss.c
/*- * ng_tcpmss.c * * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 2004, Alexey Popov <lollypop@flexuser.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 unmodified, 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. * * This software includes fragments of the following programs: * tcpmssd Ruslan Ermilov <ru@FreeBSD.org> * * $FreeBSD$ */ /* * This node is netgraph tool for workaround of PMTUD problem. It acts * like filter for IP packets. If configured, it reduces MSS of TCP SYN * packets. * * Configuration can be done by sending NGM_TCPMSS_CONFIG message. The * message sets filter for incoming packets on hook 'inHook'. Packet's * TCP MSS field is lowered to 'maxMSS' parameter and resulting packet * is sent to 'outHook'. * * XXX: statistics are updated not atomically, so they may broke on SMP. */ #include <sys/param.h> #include <sys/systm.h> #include <sys/endian.h> #include <sys/errno.h> #include <sys/kernel.h> #include <sys/malloc.h> #include <sys/mbuf.h> #include <netinet/in.h> #include <netinet/in_systm.h> #include <netinet/ip.h> #include <netinet/tcp.h> #include <netgraph/ng_message.h> #include <netgraph/netgraph.h> #include <netgraph/ng_parse.h> #include <netgraph/ng_tcpmss.h> /* Per hook info. */ typedef struct { hook_p outHook; struct ng_tcpmss_hookstat stats; } *hpriv_p; /* Netgraph methods. */ static ng_constructor_t ng_tcpmss_constructor; static ng_rcvmsg_t ng_tcpmss_rcvmsg; static ng_newhook_t ng_tcpmss_newhook; static ng_rcvdata_t ng_tcpmss_rcvdata; static ng_disconnect_t ng_tcpmss_disconnect; static int correct_mss(struct tcphdr *, int, uint16_t, int); /* Parse type for struct ng_tcpmss_hookstat. */ static const struct ng_parse_struct_field ng_tcpmss_hookstat_type_fields[] = NG_TCPMSS_HOOKSTAT_INFO; static const struct ng_parse_type ng_tcpmss_hookstat_type = { &ng_parse_struct_type, &ng_tcpmss_hookstat_type_fields }; /* Parse type for struct ng_tcpmss_config. */ static const struct ng_parse_struct_field ng_tcpmss_config_type_fields[] = NG_TCPMSS_CONFIG_INFO; static const struct ng_parse_type ng_tcpmss_config_type = { &ng_parse_struct_type, ng_tcpmss_config_type_fields }; /* List of commands and how to convert arguments to/from ASCII. */ static const struct ng_cmdlist ng_tcpmss_cmds[] = { { NGM_TCPMSS_COOKIE, NGM_TCPMSS_GET_STATS, "getstats", &ng_parse_hookbuf_type, &ng_tcpmss_hookstat_type }, { NGM_TCPMSS_COOKIE, NGM_TCPMSS_CLR_STATS, "clrstats", &ng_parse_hookbuf_type, NULL }, { NGM_TCPMSS_COOKIE, NGM_TCPMSS_GETCLR_STATS, "getclrstats", &ng_parse_hookbuf_type, &ng_tcpmss_hookstat_type }, { NGM_TCPMSS_COOKIE, NGM_TCPMSS_CONFIG, "config", &ng_tcpmss_config_type, NULL }, { 0 } }; /* Netgraph type descriptor. */ static struct ng_type ng_tcpmss_typestruct = { .version = NG_ABI_VERSION, .name = NG_TCPMSS_NODE_TYPE, .constructor = ng_tcpmss_constructor, .rcvmsg = ng_tcpmss_rcvmsg, .newhook = ng_tcpmss_newhook, .rcvdata = ng_tcpmss_rcvdata, .disconnect = ng_tcpmss_disconnect, .cmdlist = ng_tcpmss_cmds, }; NETGRAPH_INIT(tcpmss, &ng_tcpmss_typestruct); #define ERROUT(x) { error = (x); goto done; } /* * Node constructor. No special actions required. */ static int ng_tcpmss_constructor(node_p node) { return (0); } /* * Add a hook. Any unique name is OK. */ static int ng_tcpmss_newhook(node_p node, hook_p hook, const char *name) { hpriv_p priv; priv = malloc(sizeof(*priv), M_NETGRAPH, M_NOWAIT | M_ZERO); if (priv == NULL) return (ENOMEM); NG_HOOK_SET_PRIVATE(hook, priv); return (0); } /* * Receive a control message. */ static int ng_tcpmss_rcvmsg (node_p node, item_p item, hook_p lasthook) { struct ng_mesg *msg, *resp = NULL; int error = 0; NGI_GET_MSG(item, msg); switch (msg->header.typecookie) { case NGM_TCPMSS_COOKIE: switch (msg->header.cmd) { case NGM_TCPMSS_GET_STATS: case NGM_TCPMSS_CLR_STATS: case NGM_TCPMSS_GETCLR_STATS: { hook_p hook; hpriv_p priv; /* Check that message is long enough. */ if (msg->header.arglen != NG_HOOKSIZ) ERROUT(EINVAL); /* Find this hook. */ hook = ng_findhook(node, (char *)msg->data); if (hook == NULL) ERROUT(ENOENT); priv = NG_HOOK_PRIVATE(hook); /* Create response. */ if (msg->header.cmd != NGM_TCPMSS_CLR_STATS) { NG_MKRESPONSE(resp, msg, sizeof(struct ng_tcpmss_hookstat), M_NOWAIT); if (resp == NULL) ERROUT(ENOMEM); bcopy(&priv->stats, resp->data, sizeof(struct ng_tcpmss_hookstat)); } if (msg->header.cmd != NGM_TCPMSS_GET_STATS) bzero(&priv->stats, sizeof(struct ng_tcpmss_hookstat)); break; } case NGM_TCPMSS_CONFIG: { struct ng_tcpmss_config *set; hook_p in, out; hpriv_p priv; /* Check that message is long enough. */ if (msg->header.arglen != sizeof(struct ng_tcpmss_config)) ERROUT(EINVAL); set = (struct ng_tcpmss_config *)msg->data; in = ng_findhook(node, set->inHook); out = ng_findhook(node, set->outHook); if (in == NULL || out == NULL) ERROUT(ENOENT); /* Configure MSS hack. */ priv = NG_HOOK_PRIVATE(in); priv->outHook = out; priv->stats.maxMSS = set->maxMSS; break; } default: error = EINVAL; break; } break; default: error = EINVAL; break; } done: NG_RESPOND_MSG(error, node, item, resp); NG_FREE_MSG(msg); return (error); } /* * Receive data on a hook, and hack MSS. * */ static int ng_tcpmss_rcvdata(hook_p hook, item_p item) { hpriv_p priv = NG_HOOK_PRIVATE(hook); struct mbuf *m = NULL; struct ip *ip; struct tcphdr *tcp; int iphlen, tcphlen, pktlen; int pullup_len = 0; int error = 0; /* Drop packets if filter is not configured on this hook. */ if (priv->outHook == NULL) goto done; NGI_GET_M(item, m); /* Update stats on incoming hook. */ pktlen = m->m_pkthdr.len; priv->stats.Octets += pktlen; priv->stats.Packets++; /* Check whether we configured to fix MSS. */ if (priv->stats.maxMSS == 0) goto send; #define M_CHECK(length) do { \ pullup_len += length; \ if ((m)->m_pkthdr.len < pullup_len) \ goto send; \ if ((m)->m_len < pullup_len && \ (((m) = m_pullup((m), pullup_len)) == NULL)) \ ERROUT(ENOBUFS); \ } while (0) /* Check mbuf packet size and arrange for IP header. */ M_CHECK(sizeof(struct ip)); ip = mtod(m, struct ip *); /* Check IP version. */ if (ip->ip_v != IPVERSION) ERROUT(EINVAL); /* Check IP header length. */ iphlen = ip->ip_hl << 2; if (iphlen < sizeof(struct ip) || iphlen > pktlen ) ERROUT(EINVAL); /* Check if it is TCP. */ if (!(ip->ip_p == IPPROTO_TCP)) goto send; /* Check mbuf packet size and arrange for IP+TCP header */ M_CHECK(iphlen - sizeof(struct ip) + sizeof(struct tcphdr)); ip = mtod(m, struct ip *); tcp = (struct tcphdr *)((caddr_t )ip + iphlen); /* Check TCP header length. */ tcphlen = tcp->th_off << 2; if (tcphlen < sizeof(struct tcphdr) || tcphlen > pktlen - iphlen) ERROUT(EINVAL); /* Check SYN packet and has options. */ if (!(tcp->th_flags & TH_SYN) || tcphlen == sizeof(struct tcphdr)) goto send; /* Update SYN stats. */ priv->stats.SYNPkts++; M_CHECK(tcphlen - sizeof(struct tcphdr)); ip = mtod(m, struct ip *); tcp = (struct tcphdr *)((caddr_t )ip + iphlen); #undef M_CHECK /* Fix MSS and update stats. */ if (correct_mss(tcp, tcphlen, priv->stats.maxMSS, m->m_pkthdr.csum_flags)) priv->stats.FixedPkts++; send: /* Deliver frame out destination hook. */ NG_FWD_NEW_DATA(error, item, priv->outHook, m); return (error); done: NG_FREE_ITEM(item); NG_FREE_M(m); return (error); } /* * Hook disconnection. * We must check all hooks, since they may reference this one. */ static int ng_tcpmss_disconnect(hook_p hook) { node_p node = NG_HOOK_NODE(hook); hook_p hook2; LIST_FOREACH(hook2, &node->nd_hooks, hk_hooks) { hpriv_p priv = NG_HOOK_PRIVATE(hook2); if (priv->outHook == hook) priv->outHook = NULL; } free(NG_HOOK_PRIVATE(hook), M_NETGRAPH); if (NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0) ng_rmnode_self(NG_HOOK_NODE(hook)); return (0); } /* * Code from tcpmssd. */ /*- * The following macro is used to update an * internet checksum. "acc" is a 32-bit * accumulation of all the changes to the * checksum (adding in old 16-bit words and * subtracting out new words), and "cksum" * is the checksum value to be updated. */ #define TCPMSS_ADJUST_CHECKSUM(acc, cksum) do { \ acc += cksum; \ if (acc < 0) { \ acc = -acc; \ acc = (acc >> 16) + (acc & 0xffff); \ acc += acc >> 16; \ cksum = (u_short) ~acc; \ } else { \ acc = (acc >> 16) + (acc & 0xffff); \ acc += acc >> 16; \ cksum = (u_short) acc; \ } \ } while (0); static int correct_mss(struct tcphdr *tc, int hlen, uint16_t maxmss, int flags) { int olen, optlen; u_char *opt; int accumulate; int res = 0; uint16_t sum; for (olen = hlen - sizeof(struct tcphdr), opt = (u_char *)(tc + 1); olen > 0; olen -= optlen, opt += optlen) { if (*opt == TCPOPT_EOL) break; else if (*opt == TCPOPT_NOP) optlen = 1; else { optlen = *(opt + 1); if (optlen <= 0 || optlen > olen) break; if (*opt == TCPOPT_MAXSEG) { if (optlen != TCPOLEN_MAXSEG) continue; accumulate = be16dec(opt + 2); if (accumulate > maxmss) { if ((flags & CSUM_TCP) == 0) { accumulate -= maxmss; sum = be16dec(&tc->th_sum); TCPMSS_ADJUST_CHECKSUM(accumulate, sum); be16enc(&tc->th_sum, sum); } be16enc(opt + 2, maxmss); res = 1; } } } } return (res); }
Upload File
Create Folder