From owner-freebsd-ipfw@FreeBSD.ORG Tue Mar 2 11:44:43 2004 Return-Path: Delivered-To: freebsd-ipfw@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id A870316A4CF for ; Tue, 2 Mar 2004 11:44:43 -0800 (PST) Received: from www.eviloverlord.org (bgp962005bgs.derbrn01.mi.comcast.net [68.41.90.238]) by mx1.FreeBSD.org (Postfix) with ESMTP id 0356F43D39 for ; Tue, 2 Mar 2004 11:44:43 -0800 (PST) (envelope-from mgoward@eviloverlord.org) Received: from www.eviloverlord.org (localhost [127.0.0.1]) by www.eviloverlord.org (8.12.10/8.12.10) with ESMTP id i22EaPb3031464 for ; Tue, 2 Mar 2004 14:36:25 GMT (envelope-from mgoward@eviloverlord.org) Received: (from mgoward@localhost) by www.eviloverlord.org (8.12.10/8.12.10/Submit) id i22EaPaO031463 for freebsd-ipfw@freebsd.org; Tue, 2 Mar 2004 14:36:25 GMT (envelope-from mgoward) Date: Tue, 2 Mar 2004 14:36:24 +0000 From: Matt To: freebsd-ipfw@freebsd.org Message-ID: <20040302143624.GA29286@IneedAname.eviloverlord.org> Mail-Followup-To: freebsd-ipfw@freebsd.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.4.2.1i Subject: Code snippit to add ipfw rule. X-BeenThere: freebsd-ipfw@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: IPFW Technical Discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 02 Mar 2004 19:44:43 -0000 Part of an app I am playing with needs to be able to add an ipfw rule. I had though i got all of what i need from ipfw2.c and ip_fw.h but I am painfully new to C and must be missing something. Not even sure how i can get myself a more usefull error message. Any point in the right direction would be great. Thank you. 5.2.1R. Kernel is all set. firewall works fine with the real ipfw client. When this is built and run: mgoward@IneedAname 1298> gcc -Wall test.c -o test test.c: In function `main': test.c:134: warning: implicit declaration of function `err' mgoward@IneedAname 1299> sudo ./test Password: test: getsockopt(IP_FW_ADD): Invalid argument mgoward@IneedAname 1300> Here is test.c. Dont mind all the extra includes. They are all used in the bulk of the program and I was to lazy to pick and choose when i pulled this bit out to work on it alone. #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static ipfw_insn * next_cmd(ipfw_insn *cmd) { cmd += F_LEN(cmd); bzero(cmd, sizeof(*cmd)); return cmd; } /* * conditionally runs the command. */ static int do_cmd(int optname, void *optval, uintptr_t optlen) { static int s = -1; /* the socket */ int i; if (s == -1) s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); if (optname == IP_FW_GET || optname == IP_DUMMYNET_GET || optname == IP_FW_ADD) i = getsockopt(s, IPPROTO_IP, optname, optval, (socklen_t *)optlen); else i = setsockopt(s, IPPROTO_IP, optname, optval, optlen); return i; } int main () { static uint32_t cmdbuf[255], rulebuf[255]; ipfw_insn *src, *dst, *cmd; int i; struct ip_fw *rule; bzero(cmdbuf, sizeof(cmdbuf)); bzero(rulebuf, sizeof(rulebuf)); rule = (struct ip_fw *)rulebuf; cmd = (ipfw_insn *)cmdbuf; rule->rulenum = 250; rule->set = 2; cmd->opcode = O_ACCEPT; cmd->len = 1; cmd= next_cmd(cmd); /* this will hold our object and mask */ ipfw_insn_ip *d = (ipfw_insn_ip *)cmd; /* ip and mask combo object */ d->o.opcode = O_IP_SRC_MASK; /* get the in_addr in network order */ ascii2addr(AF_INET, "192.168.12.12" , &(d->addr)); ascii2addr(AF_INET, "255.255.255.255" , &(d->mask)); d->o.len = F_INSN_SIZE(ipfw_insn_ip); /* move our command pointer up one step */ cmd = next_cmd(cmd); d = (ipfw_insn_ip *)cmd; d->o.opcode = O_IP_DST_MASK; ascii2addr(AF_INET, "192.168.12.22" , &(d->addr)); ascii2addr(AF_INET, "255.255.255.255" , &(d->mask)); d->o.len = F_INSN_SIZE(ipfw_insn_ip); cmd = next_cmd(cmd); cmd->opcode = O_PROTO; cmd->len = 1; cmd->arg1 = IPPROTO_IPV4; cmd = next_cmd(cmd); dst = (ipfw_insn *)rule->cmd; for (src = (ipfw_insn *)cmdbuf; src != cmd; src += i) { i = F_LEN(src); switch (src->opcode) { case O_LOG: case O_KEEP_STATE: case O_LIMIT: break; default: bcopy(src, dst, i * sizeof(uint32_t)); dst += i; } } rule->act_ofs = dst - rule->cmd; rule->cmd_len = (uint32_t *)dst - (uint32_t *)(rule->cmd); i = (char *)dst - (char *)rule; if (do_cmd(IP_FW_ADD, rule, (uintptr_t)&i) == -1) err(EX_UNAVAILABLE, "getsockopt(%s)", "IP_FW_ADD"); return(1); } Thank you again, Matthew Goward