summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>1996-02-24 13:38:28 +0000
committerphk <phk@FreeBSD.org>1996-02-24 13:38:28 +0000
commit45a7f29691072258573e111c1034432e37e944f2 (patch)
treec2e95be8f2e89f3c4a7e2f1ecd65471c55e01cb8 /sys
parent4bcbc91c0c769ab35c42d986c2ec4a6f6cc51b8d (diff)
downloadFreeBSD-src-45a7f29691072258573e111c1034432e37e944f2.zip
FreeBSD-src-45a7f29691072258573e111c1034432e37e944f2.tar.gz
Make getsockopt() capable of handling more than one mbuf worth of data.
Use this to read rules out of ipfw. Add the lkm code to ipfw.c
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/uipc_syscalls.c19
-rw-r--r--sys/netinet/ip_fw.c109
-rw-r--r--sys/netinet/ip_fw.h14
-rw-r--r--sys/netinet/ip_input.c6
-rw-r--r--sys/netinet/raw_ip.c21
5 files changed, 121 insertions, 48 deletions
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
index f994a40..ac92bf2 100644
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)uipc_syscalls.c 8.4 (Berkeley) 2/21/94
- * $Id: uipc_syscalls.c,v 1.13 1996/01/28 23:41:40 dyson Exp $
+ * $Id: uipc_syscalls.c,v 1.14 1996/02/13 18:16:21 wollman Exp $
*/
#include "opt_ktrace.h"
@@ -991,8 +991,8 @@ getsockopt(p, uap, retval)
int *retval;
{
struct file *fp;
- struct mbuf *m = NULL;
- int valsize, error;
+ struct mbuf *m = NULL, *m0;
+ int op, i, valsize, error;
error = getsock(p->p_fd, uap->s, &fp);
if (error)
@@ -1006,9 +1006,16 @@ getsockopt(p, uap, retval)
valsize = 0;
if ((error = sogetopt((struct socket *)fp->f_data, uap->level,
uap->name, &m)) == 0 && uap->val && valsize && m != NULL) {
- if (valsize > m->m_len)
- valsize = m->m_len;
- error = copyout(mtod(m, caddr_t), uap->val, (u_int)valsize);
+ op = 0;
+ while (m && !error && op < valsize) {
+ i = min(m->m_len, (valsize - op));
+ error = copyout(mtod(m, caddr_t), uap->val, (u_int)i);
+ op += i;
+ uap->val += i;
+ m0 = m;
+ MFREE(m0,m);
+ }
+ valsize = op;
if (error == 0)
error = copyout((caddr_t)&valsize,
(caddr_t)uap->avalsize, sizeof (valsize));
diff --git a/sys/netinet/ip_fw.c b/sys/netinet/ip_fw.c
index 8a23930..49b561e 100644
--- a/sys/netinet/ip_fw.c
+++ b/sys/netinet/ip_fw.c
@@ -11,7 +11,7 @@
*
* This software is provided ``AS IS'' without any warranties of any kind.
*
- * $Id: ip_fw.c,v 1.30 1996/02/23 20:11:37 phk Exp $
+ * $Id: ip_fw.c,v 1.31 1996/02/24 00:17:32 phk Exp $
*/
/*
@@ -42,7 +42,6 @@ static int fw_verbose = 1;
static int fw_verbose = 0;
#endif
-u_short ip_fw_policy = IP_FW_P_DENY;
LIST_HEAD (ip_fw_head, ip_fw_chain) ip_fw_chain;
@@ -71,6 +70,9 @@ static int port_match __P((u_short *portptr, int nports, u_short port,
static int tcpflg_match __P((struct tcphdr *tcp, struct ip_fw *f));
static void ipfw_report __P((char *txt, int rule, struct ip *ip));
+static int (*old_chk_ptr)(struct mbuf *, struct ip *,struct ifnet *, int dir);
+static int (*old_ctl_ptr)(int,struct mbuf **);
+
/*
* Returns 1 if the port is matched by the vector, 0 otherwise
*/
@@ -140,7 +142,7 @@ ipopts_match(ip, f)
else {
optlen = cp[IPOPT_OLEN];
if (optlen <= 0 || optlen > cnt) {
- goto bad;
+ return 0; /*XXX*/
}
}
switch (opt) {
@@ -174,12 +176,6 @@ ipopts_match(ip, f)
return 1;
else
return 0;
-bad:
- if (ip_fw_policy & IP_FW_P_MBIPO)
- return 1;
- else
- return 0;
-
}
static void
@@ -570,10 +566,26 @@ check_ipfw_struct(m)
}
int
-ip_fw_ctl(stage, m)
+ip_fw_ctl(stage, mm)
int stage;
- struct mbuf *m;
+ struct mbuf **mm;
{
+ int error;
+ struct mbuf *m;
+
+ if (stage == IP_FW_GET) {
+ struct ip_fw_chain *fcp = ip_fw_chain.lh_first;
+ *mm = m = m_get(M_WAIT, MT_SOOPTS);
+ for (; fcp; fcp = fcp->chain.le_next) {
+ memcpy(m->m_data, fcp->rule, sizeof *(fcp->rule));
+ m->m_len = sizeof *(fcp->rule);
+ m->m_next = m_get(M_WAIT, MT_SOOPTS);
+ m = m->m_next;
+ m->m_len = 0;
+ }
+ return (0);
+ }
+ m = *mm;
if (stage == IP_FW_FLUSH) {
while (ip_fw_chain.lh_first != NULL &&
ip_fw_chain.lh_first->rule->fw_number != (u_short)-1) {
@@ -582,12 +594,14 @@ ip_fw_ctl(stage, m)
free(fcp->rule, M_IPFW);
free(fcp, M_IPFW);
}
+ if (m) (void)m_free(m);
return (0);
}
if (stage == IP_FW_ZERO) {
struct ip_fw_chain *fcp;
for (fcp = ip_fw_chain.lh_first; fcp; fcp = fcp->chain.le_next)
fcp->rule->fw_bcnt = fcp->rule->fw_pcnt = 0;
+ if (m) (void)m_free(m);
return (0);
}
if (m == NULL) {
@@ -598,15 +612,20 @@ ip_fw_ctl(stage, m)
if (stage == IP_FW_ADD || stage == IP_FW_DEL) {
struct ip_fw *frwl = check_ipfw_struct(m);
- if (!frwl)
+ if (!frwl) {
+ if (m) (void)m_free(m);
return (EINVAL);
+ }
if (stage == IP_FW_ADD)
- return (add_entry(&ip_fw_chain, frwl));
+ error = add_entry(&ip_fw_chain, frwl);
else
- return (del_entry(&ip_fw_chain, frwl));
+ error = del_entry(&ip_fw_chain, frwl);
+ if (m) (void)m_free(m);
+ return error;
}
dprintf(("ip_fw_ctl: unknown request %d\n", stage));
+ if (m) (void)m_free(m);
return (EINVAL);
}
@@ -615,15 +634,71 @@ ip_fw_init(void)
{
struct ip_fw deny;
- ip_fw_chk_ptr=&ip_fw_chk;
- ip_fw_ctl_ptr=&ip_fw_ctl;
+ ip_fw_chk_ptr = ip_fw_chk;
+ ip_fw_ctl_ptr = ip_fw_ctl;
LIST_INIT(&ip_fw_chain);
bzero(&deny, sizeof deny);
deny.fw_flg = IP_FW_F_ALL;
deny.fw_number = (u_short)-1;
-
add_entry(&ip_fw_chain, &deny);
printf("IP firewall initialized\n");
}
+
+#ifdef ACTUALLY_LKM_NOT_KERNEL
+
+#include <sys/exec.h>
+#include <sys/sysent.h>
+#include <sys/lkm.h>
+
+MOD_MISC(ipfw);
+
+static int
+ipfw_load(struct lkm_table *lkmtp, int cmd)
+{
+ int s=splnet();
+ struct ip_fw deny;
+
+ old_chk_ptr = ip_fw_chk_ptr;
+ old_ctl_ptr = ip_fw_ctl_ptr;
+ ip_fw_chk_ptr = ip_fw_chk;
+ ip_fw_ctl_ptr = ip_fw_ctl;
+
+ LIST_INIT(&ip_fw_chain);
+ bzero(&deny, sizeof deny);
+ deny.fw_flg = IP_FW_F_ALL;
+ deny.fw_number = (u_short)-1;
+ add_entry(&ip_fw_chain, &deny);
+
+ splx(s);
+ printf("IP firewall loaded\n");
+ return 0;
+}
+
+static int
+ipfw_unload(struct lkm_table *lkmtp, int cmd)
+{
+ int s=splnet();
+
+ ip_fw_chk_ptr = old_chk_ptr;
+ ip_fw_ctl_ptr = old_ctl_ptr;
+
+ while (ip_fw_chain.lh_first != NULL) {
+ struct ip_fw_chain *fcp = ip_fw_chain.lh_first;
+ LIST_REMOVE(ip_fw_chain.lh_first, chain);
+ free(fcp->rule, M_IPFW);
+ free(fcp, M_IPFW);
+ }
+
+ splx(s);
+ printf("IP firewall unloaded\n");
+ return 0;
+}
+
+int
+ipfw_mod(struct lkm_table *lkmtp, int cmd, int ver)
+{
+ DISPATCH(lkmtp, cmd, ver, ipfw_load, ipfw_unload, lkm_nullcmd);
+}
+#endif
diff --git a/sys/netinet/ip_fw.h b/sys/netinet/ip_fw.h
index f39688c..9f6ac09 100644
--- a/sys/netinet/ip_fw.h
+++ b/sys/netinet/ip_fw.h
@@ -11,7 +11,7 @@
*
* This software is provided ``AS IS'' without any warranties of any kind.
*
- * $Id: ip_fw.h,v 1.15 1996/02/23 15:47:52 phk Exp $
+ * $Id: ip_fw.h,v 1.16 1996/02/24 00:17:33 phk Exp $
*/
/*
@@ -115,15 +115,7 @@ struct ip_fw_chain {
#define IP_FW_DEL (IP_FW_BASE_CTL+1)
#define IP_FW_FLUSH (IP_FW_BASE_CTL+2)
#define IP_FW_ZERO (IP_FW_BASE_CTL+3)
-
-/*
- * Policy flags...
- */
-#define IP_FW_P_DENY 0x01
-#define IP_FW_P_ICMP 0x02
-#define IP_FW_P_MBIPO 0x04
-#define IP_FW_P_MASK 0x07
-
+#define IP_FW_GET (IP_FW_BASE_CTL+4)
/*
* Main firewall chains definitions and global var's definitions.
@@ -134,7 +126,7 @@ struct ip_fw_chain {
* Function pointers.
*/
extern int (*ip_fw_chk_ptr)(struct mbuf *, struct ip *,struct ifnet *, int dir);
-extern int (*ip_fw_ctl_ptr)(int,struct mbuf *);
+extern int (*ip_fw_ctl_ptr)(int,struct mbuf **);
/*
* Function definitions.
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index 15d053a..04de9cb 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)ip_input.c 8.2 (Berkeley) 1/4/94
- * $Id: ip_input.c,v 1.36 1996/02/23 15:47:53 phk Exp $
+ * $Id: ip_input.c,v 1.37 1996/02/24 00:17:34 phk Exp $
*/
#include <sys/param.h>
@@ -121,7 +121,7 @@ dummy_ip_fw_chk(m, ip, rif, dir)
int (*ip_fw_chk_ptr)(struct mbuf *, struct ip *, struct ifnet *, int dir) =
dummy_ip_fw_chk;
-int (*ip_fw_ctl_ptr)(int, struct mbuf *);
+int (*ip_fw_ctl_ptr)(int, struct mbuf **);
/*
* We need to save the IP options in case a protocol wants to respond
@@ -190,7 +190,7 @@ ip_input(struct mbuf *m)
register struct ip *ip;
register struct ipq *fp;
register struct in_ifaddr *ia;
- int hlen, s;
+ int hlen;
#ifdef DIAGNOSTIC
if ((m->m_flags & M_PKTHDR) == 0)
diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c
index 4d9916d..e8076b6 100644
--- a/sys/netinet/raw_ip.c
+++ b/sys/netinet/raw_ip.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)raw_ip.c 8.7 (Berkeley) 5/15/95
- * $Id: raw_ip.c,v 1.25 1995/12/09 20:43:53 phk Exp $
+ * $Id: raw_ip.c,v 1.26 1996/02/23 15:47:58 phk Exp $
*/
#include <sys/param.h>
@@ -218,23 +218,22 @@ rip_ctloutput(op, so, level, optname, m)
}
return (error);
+ case IP_FW_GET:
+ if (ip_fw_ctl_ptr==NULL || op == PRCO_SETOPT) {
+ if (*m) (void)m_free(*m);
+ return(EINVAL);
+ }
+ return (*ip_fw_ctl_ptr)(optname, m);
case IP_FW_ADD:
case IP_FW_DEL:
case IP_FW_FLUSH:
case IP_FW_ZERO:
- if (ip_fw_ctl_ptr==NULL) {
- if (*m)
- (void)m_free(*m);
+ if (ip_fw_ctl_ptr==NULL || op != PRCO_SETOPT) {
+ if (*m) (void)m_free(*m);
return(EINVAL);
}
- if (op == PRCO_SETOPT) {
- error=(*ip_fw_ctl_ptr)(optname, *m);
- if (*m)
- (void)m_free(*m);
- }
- else
- error=EINVAL;
+ return (*ip_fw_ctl_ptr)(optname, m);
return(error);
case IP_RSVP_ON:
OpenPOWER on IntegriCloud