1*22ce4affSfengbojiang /*-
2127dd473Swhl739 * Copyright (c) 2002-2003 Luigi Rizzo
3127dd473Swhl739 * Copyright (c) 1996 Alex Nash, Paul Traina, Poul-Henning Kamp
4127dd473Swhl739 * Copyright (c) 1994 Ugen J.S.Antsilevich
5127dd473Swhl739 *
6127dd473Swhl739 * Idea and grammar partially left from:
7127dd473Swhl739 * Copyright (c) 1993 Daniel Boulet
8127dd473Swhl739 *
9127dd473Swhl739 * Redistribution and use in source forms, with and without modification,
10127dd473Swhl739 * are permitted provided that this entire comment appears intact.
11127dd473Swhl739 *
12127dd473Swhl739 * Redistribution in binary form may occur without any restrictions.
13127dd473Swhl739 * Obviously, it would be nice if you gave credit where credit is due
14127dd473Swhl739 * but requiring it would be too onerous.
15127dd473Swhl739 *
16127dd473Swhl739 * This software is provided ``AS IS'' without any warranties of any kind.
17127dd473Swhl739 *
18127dd473Swhl739 * NEW command line interface for IP firewall facility
19127dd473Swhl739 *
20127dd473Swhl739 * $FreeBSD$
21127dd473Swhl739 *
22127dd473Swhl739 * altq interface
23127dd473Swhl739 */
24127dd473Swhl739
25*22ce4affSfengbojiang #define PFIOC_USE_LATEST
26*22ce4affSfengbojiang
27127dd473Swhl739 #include <sys/types.h>
28127dd473Swhl739 #include <sys/socket.h>
29127dd473Swhl739 #include <sys/sockio.h>
30127dd473Swhl739
31127dd473Swhl739 #include "ipfw2.h"
32127dd473Swhl739
33127dd473Swhl739 #include <err.h>
34127dd473Swhl739 #include <errno.h>
35127dd473Swhl739 #include <stdio.h>
36127dd473Swhl739 #include <stdlib.h>
37127dd473Swhl739 #include <string.h>
38127dd473Swhl739 #include <sysexits.h>
39127dd473Swhl739 #include <unistd.h>
40127dd473Swhl739 #include <fcntl.h>
41127dd473Swhl739
42127dd473Swhl739 #include <net/if.h> /* IFNAMSIZ */
43127dd473Swhl739 #include <net/pfvar.h>
44127dd473Swhl739 #include <netinet/in.h> /* in_addr */
45127dd473Swhl739 #include <netinet/ip_fw.h>
46127dd473Swhl739
47127dd473Swhl739 /*
48127dd473Swhl739 * Map between current altq queue id numbers and names.
49127dd473Swhl739 */
50127dd473Swhl739 static TAILQ_HEAD(, pf_altq) altq_entries =
51127dd473Swhl739 TAILQ_HEAD_INITIALIZER(altq_entries);
52127dd473Swhl739
53127dd473Swhl739 void
altq_set_enabled(int enabled)54127dd473Swhl739 altq_set_enabled(int enabled)
55127dd473Swhl739 {
56127dd473Swhl739 int pffd;
57127dd473Swhl739
58127dd473Swhl739 pffd = open("/dev/pf", O_RDWR);
59127dd473Swhl739 if (pffd == -1)
60127dd473Swhl739 err(EX_UNAVAILABLE,
61127dd473Swhl739 "altq support opening pf(4) control device");
62127dd473Swhl739 if (enabled) {
63127dd473Swhl739 if (ioctl(pffd, DIOCSTARTALTQ) != 0 && errno != EEXIST)
64127dd473Swhl739 err(EX_UNAVAILABLE, "enabling altq");
65127dd473Swhl739 } else {
66127dd473Swhl739 if (ioctl(pffd, DIOCSTOPALTQ) != 0 && errno != ENOENT)
67127dd473Swhl739 err(EX_UNAVAILABLE, "disabling altq");
68127dd473Swhl739 }
69127dd473Swhl739 close(pffd);
70127dd473Swhl739 }
71127dd473Swhl739
72127dd473Swhl739 static void
altq_fetch(void)73127dd473Swhl739 altq_fetch(void)
74127dd473Swhl739 {
75127dd473Swhl739 struct pfioc_altq pfioc;
76127dd473Swhl739 struct pf_altq *altq;
77127dd473Swhl739 int pffd;
78127dd473Swhl739 unsigned int mnr;
79127dd473Swhl739 static int altq_fetched = 0;
80127dd473Swhl739
81127dd473Swhl739 if (altq_fetched)
82127dd473Swhl739 return;
83127dd473Swhl739 altq_fetched = 1;
84127dd473Swhl739 pffd = open("/dev/pf", O_RDONLY);
85127dd473Swhl739 if (pffd == -1) {
86127dd473Swhl739 warn("altq support opening pf(4) control device");
87127dd473Swhl739 return;
88127dd473Swhl739 }
89127dd473Swhl739 bzero(&pfioc, sizeof(pfioc));
90*22ce4affSfengbojiang pfioc.version = PFIOC_ALTQ_VERSION;
91127dd473Swhl739 if (ioctl(pffd, DIOCGETALTQS, &pfioc) != 0) {
92127dd473Swhl739 warn("altq support getting queue list");
93127dd473Swhl739 close(pffd);
94127dd473Swhl739 return;
95127dd473Swhl739 }
96127dd473Swhl739 mnr = pfioc.nr;
97127dd473Swhl739 for (pfioc.nr = 0; pfioc.nr < mnr; pfioc.nr++) {
98127dd473Swhl739 if (ioctl(pffd, DIOCGETALTQ, &pfioc) != 0) {
99127dd473Swhl739 if (errno == EBUSY)
100127dd473Swhl739 break;
101127dd473Swhl739 warn("altq support getting queue list");
102127dd473Swhl739 close(pffd);
103127dd473Swhl739 return;
104127dd473Swhl739 }
105127dd473Swhl739 if (pfioc.altq.qid == 0)
106127dd473Swhl739 continue;
107127dd473Swhl739 altq = safe_calloc(1, sizeof(*altq));
108127dd473Swhl739 *altq = pfioc.altq;
109127dd473Swhl739 TAILQ_INSERT_TAIL(&altq_entries, altq, entries);
110127dd473Swhl739 }
111127dd473Swhl739 close(pffd);
112127dd473Swhl739 }
113127dd473Swhl739
114127dd473Swhl739 u_int32_t
altq_name_to_qid(const char * name)115127dd473Swhl739 altq_name_to_qid(const char *name)
116127dd473Swhl739 {
117127dd473Swhl739 struct pf_altq *altq;
118127dd473Swhl739
119127dd473Swhl739 altq_fetch();
120127dd473Swhl739 TAILQ_FOREACH(altq, &altq_entries, entries)
121127dd473Swhl739 if (strcmp(name, altq->qname) == 0)
122127dd473Swhl739 break;
123127dd473Swhl739 if (altq == NULL)
124127dd473Swhl739 errx(EX_DATAERR, "altq has no queue named `%s'", name);
125127dd473Swhl739 return altq->qid;
126127dd473Swhl739 }
127127dd473Swhl739
128127dd473Swhl739 static const char *
altq_qid_to_name(u_int32_t qid)129127dd473Swhl739 altq_qid_to_name(u_int32_t qid)
130127dd473Swhl739 {
131127dd473Swhl739 struct pf_altq *altq;
132127dd473Swhl739
133127dd473Swhl739 altq_fetch();
134127dd473Swhl739 TAILQ_FOREACH(altq, &altq_entries, entries)
135127dd473Swhl739 if (qid == altq->qid)
136127dd473Swhl739 break;
137127dd473Swhl739 if (altq == NULL)
138127dd473Swhl739 return NULL;
139127dd473Swhl739 return altq->qname;
140127dd473Swhl739 }
141127dd473Swhl739
142127dd473Swhl739 void
print_altq_cmd(struct buf_pr * bp,const ipfw_insn_altq * altqptr)143*22ce4affSfengbojiang print_altq_cmd(struct buf_pr *bp, const ipfw_insn_altq *altqptr)
144127dd473Swhl739 {
145127dd473Swhl739 if (altqptr) {
146127dd473Swhl739 const char *qname;
147127dd473Swhl739
148127dd473Swhl739 qname = altq_qid_to_name(altqptr->qid);
149127dd473Swhl739 if (qname == NULL)
150127dd473Swhl739 bprintf(bp, " altq ?<%u>", altqptr->qid);
151127dd473Swhl739 else
152127dd473Swhl739 bprintf(bp, " altq %s", qname);
153127dd473Swhl739 }
154127dd473Swhl739 }
155