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 * altq interface
2123c608c8SLuigi Rizzo */
2223c608c8SLuigi Rizzo
23249cc75fSPatrick Kelsey #define PFIOC_USE_LATEST
24249cc75fSPatrick Kelsey
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
altq_set_enabled(int enabled)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
altq_fetch(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));
88249cc75fSPatrick Kelsey pfioc.version = PFIOC_ALTQ_VERSION;
8923c608c8SLuigi Rizzo if (ioctl(pffd, DIOCGETALTQS, &pfioc) != 0) {
9023c608c8SLuigi Rizzo warn("altq support getting queue list");
9123c608c8SLuigi Rizzo close(pffd);
9223c608c8SLuigi Rizzo return;
9323c608c8SLuigi Rizzo }
9423c608c8SLuigi Rizzo mnr = pfioc.nr;
9523c608c8SLuigi Rizzo for (pfioc.nr = 0; pfioc.nr < mnr; pfioc.nr++) {
9623c608c8SLuigi Rizzo if (ioctl(pffd, DIOCGETALTQ, &pfioc) != 0) {
9723c608c8SLuigi Rizzo if (errno == EBUSY)
9823c608c8SLuigi Rizzo break;
9923c608c8SLuigi Rizzo warn("altq support getting queue list");
10023c608c8SLuigi Rizzo close(pffd);
10123c608c8SLuigi Rizzo return;
10223c608c8SLuigi Rizzo }
10323c608c8SLuigi Rizzo if (pfioc.altq.qid == 0)
10423c608c8SLuigi Rizzo continue;
10523c608c8SLuigi Rizzo altq = safe_calloc(1, sizeof(*altq));
10623c608c8SLuigi Rizzo *altq = pfioc.altq;
10723c608c8SLuigi Rizzo TAILQ_INSERT_TAIL(&altq_entries, altq, entries);
10823c608c8SLuigi Rizzo }
10923c608c8SLuigi Rizzo close(pffd);
11023c608c8SLuigi Rizzo }
11123c608c8SLuigi Rizzo
11223c608c8SLuigi Rizzo u_int32_t
altq_name_to_qid(const char * name)11323c608c8SLuigi Rizzo altq_name_to_qid(const char *name)
11423c608c8SLuigi Rizzo {
11523c608c8SLuigi Rizzo struct pf_altq *altq;
11623c608c8SLuigi Rizzo
11723c608c8SLuigi Rizzo altq_fetch();
11823c608c8SLuigi Rizzo TAILQ_FOREACH(altq, &altq_entries, entries)
11923c608c8SLuigi Rizzo if (strcmp(name, altq->qname) == 0)
12023c608c8SLuigi Rizzo break;
12123c608c8SLuigi Rizzo if (altq == NULL)
12223c608c8SLuigi Rizzo errx(EX_DATAERR, "altq has no queue named `%s'", name);
12323c608c8SLuigi Rizzo return altq->qid;
12423c608c8SLuigi Rizzo }
12523c608c8SLuigi Rizzo
1263e9771d2SLuigi Rizzo static const char *
altq_qid_to_name(u_int32_t qid)12723c608c8SLuigi Rizzo altq_qid_to_name(u_int32_t qid)
12823c608c8SLuigi Rizzo {
12923c608c8SLuigi Rizzo struct pf_altq *altq;
13023c608c8SLuigi Rizzo
13123c608c8SLuigi Rizzo altq_fetch();
13223c608c8SLuigi Rizzo TAILQ_FOREACH(altq, &altq_entries, entries)
13323c608c8SLuigi Rizzo if (qid == altq->qid)
13423c608c8SLuigi Rizzo break;
13523c608c8SLuigi Rizzo if (altq == NULL)
13623c608c8SLuigi Rizzo return NULL;
13723c608c8SLuigi Rizzo return altq->qname;
13823c608c8SLuigi Rizzo }
13923c608c8SLuigi Rizzo
14023c608c8SLuigi Rizzo void
print_altq_cmd(struct buf_pr * bp,const ipfw_insn_altq * altqptr)141*56707beeSMark Johnston print_altq_cmd(struct buf_pr *bp, const ipfw_insn_altq *altqptr)
14223c608c8SLuigi Rizzo {
14323c608c8SLuigi Rizzo if (altqptr) {
14423c608c8SLuigi Rizzo const char *qname;
14523c608c8SLuigi Rizzo
14623c608c8SLuigi Rizzo qname = altq_qid_to_name(altqptr->qid);
14723c608c8SLuigi Rizzo if (qname == NULL)
148912430f6SAlexander V. Chernikov bprintf(bp, " altq ?<%u>", altqptr->qid);
14923c608c8SLuigi Rizzo else
150912430f6SAlexander V. Chernikov bprintf(bp, " altq %s", qname);
15123c608c8SLuigi Rizzo }
15223c608c8SLuigi Rizzo }
153