ng_nat.c (fe267a559009cbf34f9341666fe4d88a92c02d5e) | ng_nat.c (b7841ae6501e2cbb0a3d90ea412f2591d4b17f55) |
---|---|
1/*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright 2005, Gleb Smirnoff <glebius@FreeBSD.org> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 30 unchanged lines hidden (view full) --- 39 40#include <netinet/in_systm.h> 41#include <netinet/in.h> 42#include <netinet/ip.h> 43#include <netinet/ip_var.h> 44#include <netinet/tcp.h> 45#include <machine/in_cksum.h> 46 | 1/*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright 2005, Gleb Smirnoff <glebius@FreeBSD.org> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 30 unchanged lines hidden (view full) --- 39 40#include <netinet/in_systm.h> 41#include <netinet/in.h> 42#include <netinet/ip.h> 43#include <netinet/ip_var.h> 44#include <netinet/tcp.h> 45#include <machine/in_cksum.h> 46 |
47#include <net/dlt.h> 48#include <net/ethernet.h> 49 |
|
47#include <netinet/libalias/alias.h> 48#include <netinet/libalias/alias_local.h> 49 50#include <netgraph/ng_message.h> 51#include <netgraph/ng_parse.h> 52#include <netgraph/ng_nat.h> 53#include <netgraph/netgraph.h> 54 --- 181 unchanged lines hidden (view full) --- 236 }, 237 { 238 NGM_NAT_COOKIE, 239 NGM_NAT_LIBALIAS_INFO, 240 "libaliasinfo", 241 NULL, 242 &ng_nat_libalias_info_type 243 }, | 50#include <netinet/libalias/alias.h> 51#include <netinet/libalias/alias_local.h> 52 53#include <netgraph/ng_message.h> 54#include <netgraph/ng_parse.h> 55#include <netgraph/ng_nat.h> 56#include <netgraph/netgraph.h> 57 --- 181 unchanged lines hidden (view full) --- 239 }, 240 { 241 NGM_NAT_COOKIE, 242 NGM_NAT_LIBALIAS_INFO, 243 "libaliasinfo", 244 NULL, 245 &ng_nat_libalias_info_type 246 }, |
247 { 248 NGM_NAT_COOKIE, 249 NGM_NAT_SET_DLT, 250 "setdlt", 251 &ng_parse_uint8_type, 252 NULL 253 }, 254 { 255 NGM_NAT_COOKIE, 256 NGM_NAT_GET_DLT, 257 "getdlt", 258 NULL, 259 &ng_parse_uint8_type 260 }, |
|
244 { 0 } 245}; 246 247/* Netgraph node type descriptor. */ 248static struct ng_type typestruct = { 249 .version = NG_ABI_VERSION, 250 .name = NG_NAT_NODE_TYPE, 251 .constructor = ng_nat_constructor, --- 20 unchanged lines hidden (view full) --- 272 node_p node; /* back pointer to node */ 273 hook_p in; /* hook for demasquerading */ 274 hook_p out; /* hook for masquerading */ 275 struct libalias *lib; /* libalias handler */ 276 uint32_t flags; /* status flags */ 277 uint32_t rdrcount; /* number or redirects in list */ 278 uint32_t nextid; /* for next in turn in list */ 279 struct rdrhead redirhead; /* redirect list header */ | 261 { 0 } 262}; 263 264/* Netgraph node type descriptor. */ 265static struct ng_type typestruct = { 266 .version = NG_ABI_VERSION, 267 .name = NG_NAT_NODE_TYPE, 268 .constructor = ng_nat_constructor, --- 20 unchanged lines hidden (view full) --- 289 node_p node; /* back pointer to node */ 290 hook_p in; /* hook for demasquerading */ 291 hook_p out; /* hook for masquerading */ 292 struct libalias *lib; /* libalias handler */ 293 uint32_t flags; /* status flags */ 294 uint32_t rdrcount; /* number or redirects in list */ 295 uint32_t nextid; /* for next in turn in list */ 296 struct rdrhead redirhead; /* redirect list header */ |
297 uint8_t dlt; /* DLT_XXX from bpf.h */ |
|
280}; 281typedef struct ng_nat_priv *priv_p; 282 283/* Values of flags */ 284#define NGNAT_CONNECTED 0x1 /* We have both hooks connected */ 285#define NGNAT_ADDR_DEFINED 0x2 /* NGM_NAT_SET_IPADDR happened */ 286 287static int --- 9 unchanged lines hidden (view full) --- 297 298 /* Set same ports on. */ 299 (void )LibAliasSetMode(priv->lib, PKT_ALIAS_SAME_PORTS, 300 PKT_ALIAS_SAME_PORTS); 301 302 /* Init redirects housekeeping. */ 303 priv->rdrcount = 0; 304 priv->nextid = 1; | 298}; 299typedef struct ng_nat_priv *priv_p; 300 301/* Values of flags */ 302#define NGNAT_CONNECTED 0x1 /* We have both hooks connected */ 303#define NGNAT_ADDR_DEFINED 0x2 /* NGM_NAT_SET_IPADDR happened */ 304 305static int --- 9 unchanged lines hidden (view full) --- 315 316 /* Set same ports on. */ 317 (void )LibAliasSetMode(priv->lib, PKT_ALIAS_SAME_PORTS, 318 PKT_ALIAS_SAME_PORTS); 319 320 /* Init redirects housekeeping. */ 321 priv->rdrcount = 0; 322 priv->nextid = 1; |
323 priv->dlt = DLT_RAW; |
|
305 STAILQ_INIT(&priv->redirhead); 306 307 /* Link structs together. */ 308 NG_NODE_SET_PRIVATE(node, priv); 309 priv->node = node; 310 311 /* 312 * libalias is not thread safe, so our node --- 376 unchanged lines hidden (view full) --- 689 COPY(sctpLinkCount); 690 COPY(protoLinkCount); 691 COPY(fragmentIdLinkCount); 692 COPY(fragmentPtrLinkCount); 693 COPY(sockCount); 694#undef COPY 695 } 696 break; | 324 STAILQ_INIT(&priv->redirhead); 325 326 /* Link structs together. */ 327 NG_NODE_SET_PRIVATE(node, priv); 328 priv->node = node; 329 330 /* 331 * libalias is not thread safe, so our node --- 376 unchanged lines hidden (view full) --- 708 COPY(sctpLinkCount); 709 COPY(protoLinkCount); 710 COPY(fragmentIdLinkCount); 711 COPY(fragmentPtrLinkCount); 712 COPY(sockCount); 713#undef COPY 714 } 715 break; |
716 case NGM_NAT_SET_DLT: 717 if (msg->header.arglen != sizeof(uint8_t)) { 718 error = EINVAL; 719 break; 720 } 721 switch (*(uint8_t *) msg->data) { 722 case DLT_EN10MB: 723 case DLT_RAW: 724 priv->dlt = *(uint8_t *) msg->data; 725 break; 726 default: 727 error = EINVAL; 728 break; 729 } 730 break; |
|
697 default: 698 error = EINVAL; /* unknown command */ 699 break; 700 } 701 break; | 731 default: 732 error = EINVAL; /* unknown command */ 733 break; 734 } 735 break; |
736 case NGM_NAT_GET_DLT: 737 NG_MKRESPONSE(resp, msg, sizeof(uint8_t), M_WAITOK); 738 if (resp == NULL) { 739 error = ENOMEM; 740 break; 741 } 742 *((uint8_t *) resp->data) = priv->dlt; 743 break; |
|
702 default: 703 error = EINVAL; /* unknown cookie type */ 704 break; 705 } 706 707 NG_RESPOND_MSG(error, node, item, resp); 708 NG_FREE_MSG(msg); 709 return (error); 710} 711 712static int 713ng_nat_rcvdata(hook_p hook, item_p item ) 714{ 715 const priv_p priv = NG_NODE_PRIVATE(NG_HOOK_NODE(hook)); 716 struct mbuf *m; 717 struct ip *ip; | 744 default: 745 error = EINVAL; /* unknown cookie type */ 746 break; 747 } 748 749 NG_RESPOND_MSG(error, node, item, resp); 750 NG_FREE_MSG(msg); 751 return (error); 752} 753 754static int 755ng_nat_rcvdata(hook_p hook, item_p item ) 756{ 757 const priv_p priv = NG_NODE_PRIVATE(NG_HOOK_NODE(hook)); 758 struct mbuf *m; 759 struct ip *ip; |
718 int rval, error = 0; | 760 int rval, ipofs, error = 0; |
719 char *c; 720 721 /* We have no required hooks. */ 722 if (!(priv->flags & NGNAT_CONNECTED)) { 723 NG_FREE_ITEM(item); 724 return (ENXIO); 725 } 726 --- 6 unchanged lines hidden (view full) --- 733 if ((m = m_megapullup(m, m->m_pkthdr.len)) == NULL) { 734 NGI_M(item) = NULL; /* avoid double free */ 735 NG_FREE_ITEM(item); 736 return (ENOBUFS); 737 } 738 739 NGI_M(item) = m; 740 | 761 char *c; 762 763 /* We have no required hooks. */ 764 if (!(priv->flags & NGNAT_CONNECTED)) { 765 NG_FREE_ITEM(item); 766 return (ENXIO); 767 } 768 --- 6 unchanged lines hidden (view full) --- 775 if ((m = m_megapullup(m, m->m_pkthdr.len)) == NULL) { 776 NGI_M(item) = NULL; /* avoid double free */ 777 NG_FREE_ITEM(item); 778 return (ENOBUFS); 779 } 780 781 NGI_M(item) = m; 782 |
741 c = mtod(m, char *); 742 ip = mtod(m, struct ip *); | 783 switch (priv->dlt) { 784 case DLT_RAW: 785 ipofs = 0; 786 break; 787 case DLT_EN10MB: 788 { 789 struct ether_header *eh; |
743 | 790 |
744 KASSERT(m->m_pkthdr.len == ntohs(ip->ip_len), | 791 if (m->m_pkthdr.len < sizeof(struct ether_header)) { 792 NG_FREE_ITEM(item); 793 return (ENXIO); 794 } 795 eh = mtod(m, struct ether_header *); 796 switch (ntohs(eh->ether_type)) { 797 case ETHERTYPE_IP: 798 case ETHERTYPE_IPV6: 799 ipofs = sizeof(struct ether_header); 800 break; 801 default: 802 goto send; 803 } 804 break; 805 } 806 default: 807 panic("Corrupted priv->dlt: %u", priv->dlt); 808 } 809 810 c = (char *)mtodo(m, ipofs); 811 ip = (struct ip *)mtodo(m, ipofs); 812 813 KASSERT(m->m_pkthdr.len == ipofs + ntohs(ip->ip_len), |
745 ("ng_nat: ip_len != m_pkthdr.len")); 746 747 /* 748 * We drop packet when: 749 * 1. libalias returns PKT_ALIAS_ERROR; 750 * 2. For incoming packets: 751 * a) for unresolved fragments; 752 * b) libalias returns PKT_ALIAS_IGNORED and 753 * PKT_ALIAS_DENY_INCOMING flag is set. 754 */ 755 if (hook == priv->in) { | 814 ("ng_nat: ip_len != m_pkthdr.len")); 815 816 /* 817 * We drop packet when: 818 * 1. libalias returns PKT_ALIAS_ERROR; 819 * 2. For incoming packets: 820 * a) for unresolved fragments; 821 * b) libalias returns PKT_ALIAS_IGNORED and 822 * PKT_ALIAS_DENY_INCOMING flag is set. 823 */ 824 if (hook == priv->in) { |
756 rval = LibAliasIn(priv->lib, c, m->m_len + M_TRAILINGSPACE(m)); | 825 rval = LibAliasIn(priv->lib, c, m->m_len - ipofs + 826 M_TRAILINGSPACE(m)); |
757 if (rval == PKT_ALIAS_ERROR || 758 rval == PKT_ALIAS_UNRESOLVED_FRAGMENT || 759 (rval == PKT_ALIAS_IGNORED && 760 (priv->lib->packetAliasMode & 761 PKT_ALIAS_DENY_INCOMING) != 0)) { 762 NG_FREE_ITEM(item); 763 return (EINVAL); 764 } 765 } else if (hook == priv->out) { | 827 if (rval == PKT_ALIAS_ERROR || 828 rval == PKT_ALIAS_UNRESOLVED_FRAGMENT || 829 (rval == PKT_ALIAS_IGNORED && 830 (priv->lib->packetAliasMode & 831 PKT_ALIAS_DENY_INCOMING) != 0)) { 832 NG_FREE_ITEM(item); 833 return (EINVAL); 834 } 835 } else if (hook == priv->out) { |
766 rval = LibAliasOut(priv->lib, c, m->m_len + M_TRAILINGSPACE(m)); | 836 rval = LibAliasOut(priv->lib, c, m->m_len - ipofs + 837 M_TRAILINGSPACE(m)); |
767 if (rval == PKT_ALIAS_ERROR) { 768 NG_FREE_ITEM(item); 769 return (EINVAL); 770 } 771 } else 772 panic("ng_nat: unknown hook!\n"); 773 774 if (rval == PKT_ALIAS_RESPOND) 775 m->m_flags |= M_SKIP_FIREWALL; | 838 if (rval == PKT_ALIAS_ERROR) { 839 NG_FREE_ITEM(item); 840 return (EINVAL); 841 } 842 } else 843 panic("ng_nat: unknown hook!\n"); 844 845 if (rval == PKT_ALIAS_RESPOND) 846 m->m_flags |= M_SKIP_FIREWALL; |
776 m->m_pkthdr.len = m->m_len = ntohs(ip->ip_len); | 847 m->m_pkthdr.len = m->m_len = ntohs(ip->ip_len) + ipofs; |
777 778 if ((ip->ip_off & htons(IP_OFFMASK)) == 0 && 779 ip->ip_p == IPPROTO_TCP) { 780 struct tcphdr *th = (struct tcphdr *)((caddr_t)ip + 781 (ip->ip_hl << 2)); 782 783 /* 784 * Here is our terrible HACK. --- 107 unchanged lines hidden --- | 848 849 if ((ip->ip_off & htons(IP_OFFMASK)) == 0 && 850 ip->ip_p == IPPROTO_TCP) { 851 struct tcphdr *th = (struct tcphdr *)((caddr_t)ip + 852 (ip->ip_hl << 2)); 853 854 /* 855 * Here is our terrible HACK. --- 107 unchanged lines hidden --- |