123c608c8SLuigi Rizzo /* 223c608c8SLuigi Rizzo * Copyright (c) 2002-2003 Luigi Rizzo 323c608c8SLuigi Rizzo * Copyright (c) 1996 Alex Nash, Paul Traina, Poul-Henning Kamp 423c608c8SLuigi Rizzo * Copyright (c) 1994 Ugen J.S.Antsilevich 523c608c8SLuigi Rizzo * 623c608c8SLuigi Rizzo * Idea and grammar partially left from: 723c608c8SLuigi Rizzo * Copyright (c) 1993 Daniel Boulet 823c608c8SLuigi Rizzo * 923c608c8SLuigi Rizzo * Redistribution and use in source forms, with and without modification, 1023c608c8SLuigi Rizzo * are permitted provided that this entire comment appears intact. 1123c608c8SLuigi Rizzo * 1223c608c8SLuigi Rizzo * Redistribution in binary form may occur without any restrictions. 1323c608c8SLuigi Rizzo * Obviously, it would be nice if you gave credit where credit is due 1423c608c8SLuigi Rizzo * but requiring it would be too onerous. 1523c608c8SLuigi Rizzo * 1623c608c8SLuigi Rizzo * This software is provided ``AS IS'' without any warranties of any kind. 1723c608c8SLuigi Rizzo * 1823c608c8SLuigi Rizzo * NEW command line interface for IP firewall facility 1923c608c8SLuigi Rizzo * 2023c608c8SLuigi Rizzo * $FreeBSD$ 2123c608c8SLuigi Rizzo * 2223c608c8SLuigi Rizzo * altq interface 2323c608c8SLuigi Rizzo */ 2423c608c8SLuigi Rizzo 2523c608c8SLuigi Rizzo #include <sys/types.h> 2623c608c8SLuigi Rizzo #include <sys/socket.h> 2723c608c8SLuigi Rizzo #include <sys/sockio.h> 2823c608c8SLuigi Rizzo 2923c608c8SLuigi Rizzo #include "ipfw2.h" 3023c608c8SLuigi Rizzo 3123c608c8SLuigi Rizzo #include <err.h> 3223c608c8SLuigi Rizzo #include <errno.h> 3323c608c8SLuigi Rizzo #include <stdio.h> 3423c608c8SLuigi Rizzo #include <stdlib.h> 3523c608c8SLuigi Rizzo #include <string.h> 3623c608c8SLuigi Rizzo #include <sysexits.h> 3723c608c8SLuigi Rizzo #include <unistd.h> 3823c608c8SLuigi Rizzo #include <fcntl.h> 3923c608c8SLuigi Rizzo 4023c608c8SLuigi Rizzo #include <net/if.h> /* IFNAMSIZ */ 4123c608c8SLuigi Rizzo #include <net/pfvar.h> 42cc4d3c30SLuigi Rizzo #include <netinet/in.h> /* in_addr */ 4323c608c8SLuigi Rizzo #include <netinet/ip_fw.h> 4423c608c8SLuigi Rizzo 4523c608c8SLuigi Rizzo /* 4623c608c8SLuigi Rizzo * Map between current altq queue id numbers and names. 4723c608c8SLuigi Rizzo */ 4823c608c8SLuigi Rizzo static TAILQ_HEAD(, pf_altq) altq_entries = 4923c608c8SLuigi Rizzo TAILQ_HEAD_INITIALIZER(altq_entries); 5023c608c8SLuigi Rizzo 5123c608c8SLuigi Rizzo void 5223c608c8SLuigi Rizzo altq_set_enabled(int enabled) 5323c608c8SLuigi Rizzo { 5423c608c8SLuigi Rizzo int pffd; 5523c608c8SLuigi Rizzo 5623c608c8SLuigi Rizzo pffd = open("/dev/pf", O_RDWR); 5723c608c8SLuigi Rizzo if (pffd == -1) 5823c608c8SLuigi Rizzo err(EX_UNAVAILABLE, 5923c608c8SLuigi Rizzo "altq support opening pf(4) control device"); 6023c608c8SLuigi Rizzo if (enabled) { 6123c608c8SLuigi Rizzo if (ioctl(pffd, DIOCSTARTALTQ) != 0 && errno != EEXIST) 6223c608c8SLuigi Rizzo err(EX_UNAVAILABLE, "enabling altq"); 6323c608c8SLuigi Rizzo } else { 6423c608c8SLuigi Rizzo if (ioctl(pffd, DIOCSTOPALTQ) != 0 && errno != ENOENT) 6523c608c8SLuigi Rizzo err(EX_UNAVAILABLE, "disabling altq"); 6623c608c8SLuigi Rizzo } 6723c608c8SLuigi Rizzo close(pffd); 6823c608c8SLuigi Rizzo } 6923c608c8SLuigi Rizzo 7023c608c8SLuigi Rizzo static void 7123c608c8SLuigi Rizzo altq_fetch(void) 7223c608c8SLuigi Rizzo { 7323c608c8SLuigi Rizzo struct pfioc_altq pfioc; 7423c608c8SLuigi Rizzo struct pf_altq *altq; 7523c608c8SLuigi Rizzo int pffd; 7623c608c8SLuigi Rizzo unsigned int mnr; 7723c608c8SLuigi Rizzo static int altq_fetched = 0; 7823c608c8SLuigi Rizzo 7923c608c8SLuigi Rizzo if (altq_fetched) 8023c608c8SLuigi Rizzo return; 8123c608c8SLuigi Rizzo altq_fetched = 1; 8223c608c8SLuigi Rizzo pffd = open("/dev/pf", O_RDONLY); 8323c608c8SLuigi Rizzo if (pffd == -1) { 8423c608c8SLuigi Rizzo warn("altq support opening pf(4) control device"); 8523c608c8SLuigi Rizzo return; 8623c608c8SLuigi Rizzo } 8723c608c8SLuigi Rizzo bzero(&pfioc, sizeof(pfioc)); 8823c608c8SLuigi Rizzo if (ioctl(pffd, DIOCGETALTQS, &pfioc) != 0) { 8923c608c8SLuigi Rizzo warn("altq support getting queue list"); 9023c608c8SLuigi Rizzo close(pffd); 9123c608c8SLuigi Rizzo return; 9223c608c8SLuigi Rizzo } 9323c608c8SLuigi Rizzo mnr = pfioc.nr; 9423c608c8SLuigi Rizzo for (pfioc.nr = 0; pfioc.nr < mnr; pfioc.nr++) { 9523c608c8SLuigi Rizzo if (ioctl(pffd, DIOCGETALTQ, &pfioc) != 0) { 9623c608c8SLuigi Rizzo if (errno == EBUSY) 9723c608c8SLuigi Rizzo break; 9823c608c8SLuigi Rizzo warn("altq support getting queue list"); 9923c608c8SLuigi Rizzo close(pffd); 10023c608c8SLuigi Rizzo return; 10123c608c8SLuigi Rizzo } 10223c608c8SLuigi Rizzo if (pfioc.altq.qid == 0) 10323c608c8SLuigi Rizzo continue; 10423c608c8SLuigi Rizzo altq = safe_calloc(1, sizeof(*altq)); 10523c608c8SLuigi Rizzo *altq = pfioc.altq; 10623c608c8SLuigi Rizzo TAILQ_INSERT_TAIL(&altq_entries, altq, entries); 10723c608c8SLuigi Rizzo } 10823c608c8SLuigi Rizzo close(pffd); 10923c608c8SLuigi Rizzo } 11023c608c8SLuigi Rizzo 11123c608c8SLuigi Rizzo u_int32_t 11223c608c8SLuigi Rizzo altq_name_to_qid(const char *name) 11323c608c8SLuigi Rizzo { 11423c608c8SLuigi Rizzo struct pf_altq *altq; 11523c608c8SLuigi Rizzo 11623c608c8SLuigi Rizzo altq_fetch(); 11723c608c8SLuigi Rizzo TAILQ_FOREACH(altq, &altq_entries, entries) 11823c608c8SLuigi Rizzo if (strcmp(name, altq->qname) == 0) 11923c608c8SLuigi Rizzo break; 12023c608c8SLuigi Rizzo if (altq == NULL) 12123c608c8SLuigi Rizzo errx(EX_DATAERR, "altq has no queue named `%s'", name); 12223c608c8SLuigi Rizzo return altq->qid; 12323c608c8SLuigi Rizzo } 12423c608c8SLuigi Rizzo 1253e9771d2SLuigi Rizzo static const char * 12623c608c8SLuigi Rizzo altq_qid_to_name(u_int32_t qid) 12723c608c8SLuigi Rizzo { 12823c608c8SLuigi Rizzo struct pf_altq *altq; 12923c608c8SLuigi Rizzo 13023c608c8SLuigi Rizzo altq_fetch(); 13123c608c8SLuigi Rizzo TAILQ_FOREACH(altq, &altq_entries, entries) 13223c608c8SLuigi Rizzo if (qid == altq->qid) 13323c608c8SLuigi Rizzo break; 13423c608c8SLuigi Rizzo if (altq == NULL) 13523c608c8SLuigi Rizzo return NULL; 13623c608c8SLuigi Rizzo return altq->qname; 13723c608c8SLuigi Rizzo } 13823c608c8SLuigi Rizzo 13923c608c8SLuigi Rizzo void 140*912430f6SAlexander V. Chernikov print_altq_cmd(struct buf_pr *bp, ipfw_insn_altq *altqptr) 14123c608c8SLuigi Rizzo { 14223c608c8SLuigi Rizzo if (altqptr) { 14323c608c8SLuigi Rizzo const char *qname; 14423c608c8SLuigi Rizzo 14523c608c8SLuigi Rizzo qname = altq_qid_to_name(altqptr->qid); 14623c608c8SLuigi Rizzo if (qname == NULL) 147*912430f6SAlexander V. Chernikov bprintf(bp, " altq ?<%u>", altqptr->qid); 14823c608c8SLuigi Rizzo else 149*912430f6SAlexander V. Chernikov bprintf(bp, " altq %s", qname); 15023c608c8SLuigi Rizzo } 15123c608c8SLuigi Rizzo } 152