1d17aef79SPedro F. Giffuni /*- 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 25*249cc75fSPatrick Kelsey #define PFIOC_USE_LATEST 26*249cc75fSPatrick Kelsey 2723c608c8SLuigi Rizzo #include <sys/types.h> 2823c608c8SLuigi Rizzo #include <sys/socket.h> 2923c608c8SLuigi Rizzo #include <sys/sockio.h> 3023c608c8SLuigi Rizzo 3123c608c8SLuigi Rizzo #include "ipfw2.h" 3223c608c8SLuigi Rizzo 3323c608c8SLuigi Rizzo #include <err.h> 3423c608c8SLuigi Rizzo #include <errno.h> 3523c608c8SLuigi Rizzo #include <stdio.h> 3623c608c8SLuigi Rizzo #include <stdlib.h> 3723c608c8SLuigi Rizzo #include <string.h> 3823c608c8SLuigi Rizzo #include <sysexits.h> 3923c608c8SLuigi Rizzo #include <unistd.h> 4023c608c8SLuigi Rizzo #include <fcntl.h> 4123c608c8SLuigi Rizzo 4223c608c8SLuigi Rizzo #include <net/if.h> /* IFNAMSIZ */ 4323c608c8SLuigi Rizzo #include <net/pfvar.h> 44cc4d3c30SLuigi Rizzo #include <netinet/in.h> /* in_addr */ 4523c608c8SLuigi Rizzo #include <netinet/ip_fw.h> 4623c608c8SLuigi Rizzo 4723c608c8SLuigi Rizzo /* 4823c608c8SLuigi Rizzo * Map between current altq queue id numbers and names. 4923c608c8SLuigi Rizzo */ 5023c608c8SLuigi Rizzo static TAILQ_HEAD(, pf_altq) altq_entries = 5123c608c8SLuigi Rizzo TAILQ_HEAD_INITIALIZER(altq_entries); 5223c608c8SLuigi Rizzo 5323c608c8SLuigi Rizzo void 5423c608c8SLuigi Rizzo altq_set_enabled(int enabled) 5523c608c8SLuigi Rizzo { 5623c608c8SLuigi Rizzo int pffd; 5723c608c8SLuigi Rizzo 5823c608c8SLuigi Rizzo pffd = open("/dev/pf", O_RDWR); 5923c608c8SLuigi Rizzo if (pffd == -1) 6023c608c8SLuigi Rizzo err(EX_UNAVAILABLE, 6123c608c8SLuigi Rizzo "altq support opening pf(4) control device"); 6223c608c8SLuigi Rizzo if (enabled) { 6323c608c8SLuigi Rizzo if (ioctl(pffd, DIOCSTARTALTQ) != 0 && errno != EEXIST) 6423c608c8SLuigi Rizzo err(EX_UNAVAILABLE, "enabling altq"); 6523c608c8SLuigi Rizzo } else { 6623c608c8SLuigi Rizzo if (ioctl(pffd, DIOCSTOPALTQ) != 0 && errno != ENOENT) 6723c608c8SLuigi Rizzo err(EX_UNAVAILABLE, "disabling altq"); 6823c608c8SLuigi Rizzo } 6923c608c8SLuigi Rizzo close(pffd); 7023c608c8SLuigi Rizzo } 7123c608c8SLuigi Rizzo 7223c608c8SLuigi Rizzo static void 7323c608c8SLuigi Rizzo altq_fetch(void) 7423c608c8SLuigi Rizzo { 7523c608c8SLuigi Rizzo struct pfioc_altq pfioc; 7623c608c8SLuigi Rizzo struct pf_altq *altq; 7723c608c8SLuigi Rizzo int pffd; 7823c608c8SLuigi Rizzo unsigned int mnr; 7923c608c8SLuigi Rizzo static int altq_fetched = 0; 8023c608c8SLuigi Rizzo 8123c608c8SLuigi Rizzo if (altq_fetched) 8223c608c8SLuigi Rizzo return; 8323c608c8SLuigi Rizzo altq_fetched = 1; 8423c608c8SLuigi Rizzo pffd = open("/dev/pf", O_RDONLY); 8523c608c8SLuigi Rizzo if (pffd == -1) { 8623c608c8SLuigi Rizzo warn("altq support opening pf(4) control device"); 8723c608c8SLuigi Rizzo return; 8823c608c8SLuigi Rizzo } 8923c608c8SLuigi Rizzo bzero(&pfioc, sizeof(pfioc)); 90*249cc75fSPatrick Kelsey pfioc.version = PFIOC_ALTQ_VERSION; 9123c608c8SLuigi Rizzo if (ioctl(pffd, DIOCGETALTQS, &pfioc) != 0) { 9223c608c8SLuigi Rizzo warn("altq support getting queue list"); 9323c608c8SLuigi Rizzo close(pffd); 9423c608c8SLuigi Rizzo return; 9523c608c8SLuigi Rizzo } 9623c608c8SLuigi Rizzo mnr = pfioc.nr; 9723c608c8SLuigi Rizzo for (pfioc.nr = 0; pfioc.nr < mnr; pfioc.nr++) { 9823c608c8SLuigi Rizzo if (ioctl(pffd, DIOCGETALTQ, &pfioc) != 0) { 9923c608c8SLuigi Rizzo if (errno == EBUSY) 10023c608c8SLuigi Rizzo break; 10123c608c8SLuigi Rizzo warn("altq support getting queue list"); 10223c608c8SLuigi Rizzo close(pffd); 10323c608c8SLuigi Rizzo return; 10423c608c8SLuigi Rizzo } 10523c608c8SLuigi Rizzo if (pfioc.altq.qid == 0) 10623c608c8SLuigi Rizzo continue; 10723c608c8SLuigi Rizzo altq = safe_calloc(1, sizeof(*altq)); 10823c608c8SLuigi Rizzo *altq = pfioc.altq; 10923c608c8SLuigi Rizzo TAILQ_INSERT_TAIL(&altq_entries, altq, entries); 11023c608c8SLuigi Rizzo } 11123c608c8SLuigi Rizzo close(pffd); 11223c608c8SLuigi Rizzo } 11323c608c8SLuigi Rizzo 11423c608c8SLuigi Rizzo u_int32_t 11523c608c8SLuigi Rizzo altq_name_to_qid(const char *name) 11623c608c8SLuigi Rizzo { 11723c608c8SLuigi Rizzo struct pf_altq *altq; 11823c608c8SLuigi Rizzo 11923c608c8SLuigi Rizzo altq_fetch(); 12023c608c8SLuigi Rizzo TAILQ_FOREACH(altq, &altq_entries, entries) 12123c608c8SLuigi Rizzo if (strcmp(name, altq->qname) == 0) 12223c608c8SLuigi Rizzo break; 12323c608c8SLuigi Rizzo if (altq == NULL) 12423c608c8SLuigi Rizzo errx(EX_DATAERR, "altq has no queue named `%s'", name); 12523c608c8SLuigi Rizzo return altq->qid; 12623c608c8SLuigi Rizzo } 12723c608c8SLuigi Rizzo 1283e9771d2SLuigi Rizzo static const char * 12923c608c8SLuigi Rizzo altq_qid_to_name(u_int32_t qid) 13023c608c8SLuigi Rizzo { 13123c608c8SLuigi Rizzo struct pf_altq *altq; 13223c608c8SLuigi Rizzo 13323c608c8SLuigi Rizzo altq_fetch(); 13423c608c8SLuigi Rizzo TAILQ_FOREACH(altq, &altq_entries, entries) 13523c608c8SLuigi Rizzo if (qid == altq->qid) 13623c608c8SLuigi Rizzo break; 13723c608c8SLuigi Rizzo if (altq == NULL) 13823c608c8SLuigi Rizzo return NULL; 13923c608c8SLuigi Rizzo return altq->qname; 14023c608c8SLuigi Rizzo } 14123c608c8SLuigi Rizzo 14223c608c8SLuigi Rizzo void 143912430f6SAlexander V. Chernikov print_altq_cmd(struct buf_pr *bp, ipfw_insn_altq *altqptr) 14423c608c8SLuigi Rizzo { 14523c608c8SLuigi Rizzo if (altqptr) { 14623c608c8SLuigi Rizzo const char *qname; 14723c608c8SLuigi Rizzo 14823c608c8SLuigi Rizzo qname = altq_qid_to_name(altqptr->qid); 14923c608c8SLuigi Rizzo if (qname == NULL) 150912430f6SAlexander V. Chernikov bprintf(bp, " altq ?<%u>", altqptr->qid); 15123c608c8SLuigi Rizzo else 152912430f6SAlexander V. Chernikov bprintf(bp, " altq %s", qname); 15323c608c8SLuigi Rizzo } 15423c608c8SLuigi Rizzo } 155