Compare commits
2296 Commits
v2.30
...
v2.92test1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ff30fa4b91 | ||
|
|
c91c66ee63 | ||
|
|
fc9f6985ab | ||
|
|
ea5b0e64e2 | ||
|
|
e775264539 | ||
|
|
d976d94e3d | ||
|
|
3034746748 | ||
|
|
3ceea9e755 | ||
|
|
dfcef19fb4 | ||
|
|
f74b74e521 | ||
|
|
c9342cb556 | ||
|
|
2b844b8c83 | ||
|
|
65e9a8957c | ||
|
|
da868a2fbe | ||
|
|
bceb5287b9 | ||
|
|
84445dec26 | ||
|
|
c70b92b2a4 | ||
|
|
57e582492b | ||
|
|
ec8f3e65c1 | ||
|
|
15841f187d | ||
|
|
ade97495e6 | ||
|
|
2b19285724 | ||
|
|
a444715bf0 | ||
|
|
14e81b6976 | ||
|
|
6ce7f2d55a | ||
|
|
287d6bc88d | ||
|
|
c378d2c1de | ||
|
|
5846f749e5 | ||
|
|
c9a4240ec4 | ||
|
|
e7b87dee85 | ||
|
|
90b248582c | ||
|
|
ebef27f321 | ||
|
|
1861a881eb | ||
|
|
96bdb42d40 | ||
|
|
c7a909ad65 | ||
|
|
baf3c57af5 | ||
|
|
e48a2af4f5 | ||
|
|
91b800cc62 | ||
|
|
075e4a56b7 | ||
|
|
48658ebc54 | ||
|
|
692ed0dd32 | ||
|
|
43805c1859 | ||
|
|
4fbe1add95 | ||
|
|
57c7ae8fc0 | ||
|
|
d1008215dc | ||
|
|
b0aa604fcc | ||
|
|
8ddabd11bc | ||
|
|
98189ff988 | ||
|
|
e86d53c438 | ||
|
|
e127a972d1 | ||
|
|
a458c2bfb0 | ||
|
|
9e67099ce7 | ||
|
|
cfa1313e1f | ||
|
|
e3a2c8dadf | ||
|
|
95b74a7acf | ||
|
|
ae57f84061 | ||
|
|
0620309b73 | ||
|
|
942a35f517 | ||
|
|
83658efbf4 | ||
|
|
b0b4d90b6a | ||
|
|
bdce03f928 | ||
|
|
d390dc0338 | ||
|
|
105c25e561 | ||
|
|
67e07b7fe8 | ||
|
|
f5659b406b | ||
|
|
484fea238a | ||
|
|
1e587bec57 | ||
|
|
581c201aa8 | ||
|
|
5487f6979e | ||
|
|
99f12e3541 | ||
|
|
7c1212e3d1 | ||
|
|
0ccbdf8087 | ||
|
|
57f0489f38 | ||
|
|
3e659bd4ec | ||
|
|
9af15871e6 | ||
|
|
5897e79d05 | ||
|
|
fc9135ca9f | ||
|
|
e427d4b0e6 | ||
|
|
9df1bd0cc1 | ||
|
|
5990074ab0 | ||
|
|
dbb69bd192 | ||
|
|
d17581c4c6 | ||
|
|
2c9ed7f425 | ||
|
|
717ff6adc3 | ||
|
|
f9f8d19bf5 | ||
|
|
535be2f5d3 | ||
|
|
bceab45dbe | ||
|
|
368ceff6e0 | ||
|
|
77c4e95d4a | ||
|
|
e44165c0f7 | ||
|
|
a1a214c393 | ||
|
|
94b7144a1b | ||
|
|
e72910dec8 | ||
|
|
0b6144583b | ||
|
|
f31667317d | ||
|
|
5226b712a3 | ||
|
|
1f84cde024 | ||
|
|
046bfa2af0 | ||
|
|
0762732647 | ||
|
|
efb8f10450 | ||
|
|
6dbdf16fd1 | ||
|
|
6e6a45a7d9 | ||
|
|
a4569c22cc | ||
|
|
199e65c4d9 | ||
|
|
bb8811d472 | ||
|
|
995a16ca0c | ||
|
|
65f9c1aca1 | ||
|
|
b72ecb3a59 | ||
|
|
c221030f89 | ||
|
|
5bbea085d0 | ||
|
|
622cf03ab9 | ||
|
|
8ce27433f8 | ||
|
|
5d894620b4 | ||
|
|
71766c0c35 | ||
|
|
da58455508 | ||
|
|
b915c9a661 | ||
|
|
424aaa0f9d | ||
|
|
c72c895869 | ||
|
|
b7156116c2 | ||
|
|
7d915a0bb9 | ||
|
|
509afcd1d2 | ||
|
|
51343bd9a2 | ||
|
|
b58276a73c | ||
|
|
f162d344c0 | ||
|
|
0003db15cb | ||
|
|
275f4a4475 | ||
|
|
12e4565fef | ||
|
|
7af26eed32 | ||
|
|
63dc6eb316 | ||
|
|
6656790f24 | ||
|
|
c8de423038 | ||
|
|
c52653f97c | ||
|
|
e24c341068 | ||
|
|
5ef6c8c24f | ||
|
|
7c348a0b73 | ||
|
|
d578da0665 | ||
|
|
8949ef44b4 | ||
|
|
3ac11cdd98 | ||
|
|
5d49fa112d | ||
|
|
d29d19e654 | ||
|
|
49ea7db74e | ||
|
|
fcb40ee73d | ||
|
|
0f437b3b5e | ||
|
|
8a5fe8ce6b | ||
|
|
2a664c03db | ||
|
|
4902807879 | ||
|
|
742af6e4b9 | ||
|
|
3eb008c36d | ||
|
|
32248ebd5b | ||
|
|
5d32f35bdc | ||
|
|
d6379cd923 | ||
|
|
9f7e9ba46f | ||
|
|
80498fab01 | ||
|
|
ea84abe3e9 | ||
|
|
0526792ebb | ||
|
|
ab177cb153 | ||
|
|
3b74df4f55 | ||
|
|
5483fead6a | ||
|
|
7199531ff1 | ||
|
|
5a1f2c577d | ||
|
|
6c9bc0156a | ||
|
|
da2cc84854 | ||
|
|
a8088e331a | ||
|
|
41d2ae3203 | ||
|
|
c6bc22adc7 | ||
|
|
9c057566d5 | ||
|
|
32a8f3e009 | ||
|
|
481ff0ed10 | ||
|
|
f04cf8506a | ||
|
|
04d7693d86 | ||
|
|
4ea23f7ea1 | ||
|
|
163c05c61d | ||
|
|
d2790914df | ||
|
|
334e144c36 | ||
|
|
8bd54efceb | ||
|
|
e5e8c14d87 | ||
|
|
e778a28eee | ||
|
|
4cf2f757ec | ||
|
|
ae85ea3858 | ||
|
|
b087cf4a6c | ||
|
|
0adaf13438 | ||
|
|
b5ac983bf6 | ||
|
|
498794ad85 | ||
|
|
467fbd1086 | ||
|
|
7b7aef903e | ||
|
|
09a1839272 | ||
|
|
1b76e1c8ec | ||
|
|
959d991d10 | ||
|
|
ed6d29a784 | ||
|
|
5d6399b71c | ||
|
|
3b6df06fb8 | ||
|
|
a9d46d42cb | ||
|
|
0338aa4586 | ||
|
|
d15d371051 | ||
|
|
1c26ec2876 | ||
|
|
e9a7cd0a50 | ||
|
|
f5cdb007d8 | ||
|
|
46288c7e90 | ||
|
|
d7d682637d | ||
|
|
f006be7842 | ||
|
|
550c368ade | ||
|
|
b8ff4bb762 | ||
|
|
9adbf009a6 | ||
|
|
ccff85ad72 | ||
|
|
4c590320ec | ||
|
|
89aad01468 | ||
|
|
de6f914654 | ||
|
|
1ed783b8d7 | ||
|
|
3705ec5592 | ||
|
|
b6769234bc | ||
|
|
214a046f47 | ||
|
|
b38da6b191 | ||
|
|
9621c16a78 | ||
|
|
3ae7f1ab0d | ||
|
|
39de57499e | ||
|
|
3c91bca943 | ||
|
|
76bceb06c4 | ||
|
|
6f23a0a75e | ||
|
|
06945c4b77 | ||
|
|
c5aa221e44 | ||
|
|
bfefd6e38c | ||
|
|
59d30390c9 | ||
|
|
51471cafa5 | ||
|
|
be73efc020 | ||
|
|
40595f80d9 | ||
|
|
8c8e5385fd | ||
|
|
3de7289bd6 | ||
|
|
febeea9d01 | ||
|
|
762a3f2430 | ||
|
|
6d35601da4 | ||
|
|
a827127c77 | ||
|
|
d4a6f3a93e | ||
|
|
86c15032ba | ||
|
|
12ddb2a4b9 | ||
|
|
db07664f2a | ||
|
|
1205fc3541 | ||
|
|
3a8ebcac77 | ||
|
|
729e54b386 | ||
|
|
a61dbc84bf | ||
|
|
3cbd4b0fc0 | ||
|
|
75965b19bd | ||
|
|
830459d3a1 | ||
|
|
aa9e9651a1 | ||
|
|
9142942483 | ||
|
|
68fe0d78bb | ||
|
|
c9d7b983c4 | ||
|
|
7c07dc3526 | ||
|
|
cd93d15ab1 | ||
|
|
34bbb7a1b8 | ||
|
|
b5820d1fd8 | ||
|
|
2748d4e901 | ||
|
|
63ba726e1f | ||
|
|
f1beb79429 | ||
|
|
cd4db8246e | ||
|
|
69877f565a | ||
|
|
744231d995 | ||
|
|
65c2d6afd6 | ||
|
|
b27b94cfdc | ||
|
|
b8b5b734b4 | ||
|
|
568fb02449 | ||
|
|
77ef9b2603 | ||
|
|
416390f996 | ||
|
|
24804b7431 | ||
|
|
1fe9d2ba45 | ||
|
|
3868066085 | ||
|
|
a889c554a7 | ||
|
|
ca8d04a8ff | ||
|
|
8b606543a3 | ||
|
|
d16b995756 | ||
|
|
768b45a023 | ||
|
|
3b5ddf37d9 | ||
|
|
9bbf098a97 | ||
|
|
6536187b62 | ||
|
|
50adf82199 | ||
|
|
1419de285f | ||
|
|
31c91b40bd | ||
|
|
1d6fe0ea84 | ||
|
|
d774add784 | ||
|
|
7500157cff | ||
|
|
52e6ad2761 | ||
|
|
bcb46809dc | ||
|
|
33635d8564 | ||
|
|
bd188e306a | ||
|
|
aaba66efbd | ||
|
|
597378cdf5 | ||
|
|
15dcdc824a | ||
|
|
86ee779e22 | ||
|
|
df242de5c6 | ||
|
|
b14aa762ff | ||
|
|
a78487a4df | ||
|
|
3a601d06bd | ||
|
|
047256a6d8 | ||
|
|
c244d92d8a | ||
|
|
138e1e2a2d | ||
|
|
153eeb070b | ||
|
|
a3c8b75972 | ||
|
|
042c64273d | ||
|
|
638c7c4d20 | ||
|
|
88fc6c8023 | ||
|
|
3fb10cd0d8 | ||
|
|
ff28a485cf | ||
|
|
1f0f86a0d0 | ||
|
|
2842972035 | ||
|
|
5a9eae429a | ||
|
|
9461807011 | ||
|
|
00be8b39e2 | ||
|
|
ef5aac95d4 | ||
|
|
ef8e930e42 | ||
|
|
eb92fb32b7 | ||
|
|
9a698434dd | ||
|
|
f5ef0f064c | ||
|
|
997982f78b | ||
|
|
7d6b68c5d7 | ||
|
|
137ae2e9cf | ||
|
|
5dc14b6e05 | ||
|
|
0427e37116 | ||
|
|
e5e8cae1ca | ||
|
|
7f42ca8af8 | ||
|
|
e4251eb13b | ||
|
|
5083876910 | ||
|
|
f172fdbb77 | ||
|
|
3822825e54 | ||
|
|
1da54210fc | ||
|
|
43a2a66531 | ||
|
|
e6841ea2e0 | ||
|
|
e939b45c9f | ||
|
|
e3068ed111 | ||
|
|
efbf80be58 | ||
|
|
022ad63f0c | ||
|
|
02f8754339 | ||
|
|
142456cfd0 | ||
|
|
207ce40db2 | ||
|
|
881eaa4dbc | ||
|
|
d6d7527c95 | ||
|
|
11b4be2036 | ||
|
|
3e306c1202 | ||
|
|
7f227a83f2 | ||
|
|
9ed3ee67ec | ||
|
|
1f9215f5f9 | ||
|
|
f52cfdd8c3 | ||
|
|
2fc904111d | ||
|
|
262dadf50e | ||
|
|
6c596f1cc1 | ||
|
|
dafa16c400 | ||
|
|
1db9943c68 | ||
|
|
5b868c213b | ||
|
|
2d8905dafd | ||
|
|
9002108551 | ||
|
|
d3c21c596e | ||
|
|
34fac952b6 | ||
|
|
92c32e0bac | ||
|
|
1bcad67806 | ||
|
|
fe9a134baf | ||
|
|
930428fb97 | ||
|
|
936be022d9 | ||
|
|
0017dd74d5 | ||
|
|
0ba25a0512 | ||
|
|
a176cf1bc3 | ||
|
|
fdd9a96a8c | ||
|
|
b87d7aa041 | ||
|
|
f753e7eba6 | ||
|
|
78a5a21655 | ||
|
|
a5cbe6d112 | ||
|
|
9403664616 | ||
|
|
f32498465d | ||
|
|
fa45e06431 | ||
|
|
6722ec6c78 | ||
|
|
d882dfdae9 | ||
|
|
a2ee2426bf | ||
|
|
84bd46ddd7 | ||
|
|
271790685a | ||
|
|
7a74037267 | ||
|
|
9a9f6e147c | ||
|
|
8f2d432799 | ||
|
|
92eab03b12 | ||
|
|
1ba4ae2830 | ||
|
|
0076481dfd | ||
|
|
c0e731d545 | ||
|
|
3f56bb8ba1 | ||
|
|
e518e87533 | ||
|
|
c4b9bc63e0 | ||
|
|
1d53d958bb | ||
|
|
d334e7c34f | ||
|
|
d21438a7df | ||
|
|
24c3b5b3d4 | ||
|
|
4447d48bb9 | ||
|
|
04cc2ae1a6 | ||
|
|
32588c755a | ||
|
|
84a6d07cdd | ||
|
|
d6c69f6bdb | ||
|
|
ce372917fe | ||
|
|
09d741f58a | ||
|
|
0666ae3d27 | ||
|
|
ba4c7d906b | ||
|
|
f4b2813818 | ||
|
|
5586934da0 | ||
|
|
6134b94c02 | ||
|
|
05e6728e98 | ||
|
|
6578acd668 | ||
|
|
b5581ed173 | ||
|
|
508d6b4885 | ||
|
|
ef6efd69ed | ||
|
|
151d7dc5ea | ||
|
|
20b4a4ea5b | ||
|
|
770bce967c | ||
|
|
a267a9e489 | ||
|
|
f65d210012 | ||
|
|
858bfcf261 | ||
|
|
9b801c4e72 | ||
|
|
1a98d1a94f | ||
|
|
03345ecefe | ||
|
|
191924576c | ||
|
|
756a1dcc19 | ||
|
|
3ab6dd1c37 | ||
|
|
4458d87289 | ||
|
|
b7f62475d0 | ||
|
|
4732aa663b | ||
|
|
c27cfeaa7b | ||
|
|
bb6f6bae0b | ||
|
|
f4c87b504b | ||
|
|
e426c2d3bc | ||
|
|
6279d9eaf3 | ||
|
|
12949aa0c0 | ||
|
|
84f3357dd9 | ||
|
|
4333d5d93a | ||
|
|
fa580ad3eb | ||
|
|
292dfa653e | ||
|
|
7fbf1cce7b | ||
|
|
dbceeb4178 | ||
|
|
ed200fa001 | ||
|
|
b5dafc0b7e | ||
|
|
fc664d114d | ||
|
|
c6d4c33d61 | ||
|
|
bf1fc6c6fd | ||
|
|
b18e9c8c61 | ||
|
|
a3293bb242 | ||
|
|
4e2a4b8788 | ||
|
|
2362784bc0 | ||
|
|
b2cec1b881 | ||
|
|
a946857133 | ||
|
|
10cd342f5c | ||
|
|
27ce754b3d | ||
|
|
3ab0ad8748 | ||
|
|
4308236262 | ||
|
|
ebd8350300 | ||
|
|
8285d335f4 | ||
|
|
9db275ebea | ||
|
|
1f8f78a49b | ||
|
|
c2f129ba3d | ||
|
|
07c47416a9 | ||
|
|
8f2a62b386 | ||
|
|
a6c0edd4f4 | ||
|
|
ff43d35aee | ||
|
|
70fca205be | ||
|
|
1033130b6c | ||
|
|
8cfcd9ff63 | ||
|
|
80a6c16dcc | ||
|
|
553c4c99cc | ||
|
|
4165c1331b | ||
|
|
b2690415bf | ||
|
|
011f8cf1d0 | ||
|
|
2748fb81e2 | ||
|
|
46312909d9 | ||
|
|
41adecad14 | ||
|
|
ea5d8c56a0 | ||
|
|
d242cbffa4 | ||
|
|
1c8855ed10 | ||
|
|
ea33a01303 | ||
|
|
18b1d1424e | ||
|
|
1176cd58c9 | ||
|
|
44a4643b62 | ||
|
|
ed96efd865 | ||
|
|
e3093b532c | ||
|
|
9560658c5b | ||
|
|
37a70d39e0 | ||
|
|
72fac0810c | ||
|
|
c166c07a93 | ||
|
|
39a625ff72 | ||
|
|
ad32ca18a7 | ||
|
|
efea282396 | ||
|
|
33d6a01cd3 | ||
|
|
d290630d31 | ||
|
|
d2ad5dc073 | ||
|
|
68ab5127af | ||
|
|
089a11f340 | ||
|
|
de1d04eb66 | ||
|
|
ed4e7defd7 | ||
|
|
267ab619c4 | ||
|
|
0140454ba2 | ||
|
|
2c60441239 | ||
|
|
cbbd56c965 | ||
|
|
2561f9fe0e | ||
|
|
47aefca5e4 | ||
|
|
981fb03710 | ||
|
|
ef2f8d70d2 | ||
|
|
d9995a1add | ||
|
|
ea7a05ad43 | ||
|
|
26bbf5a314 | ||
|
|
c147329823 | ||
|
|
eb88eed1fc | ||
|
|
8312a3ba4f | ||
|
|
35f93081dc | ||
|
|
de372d6914 | ||
|
|
4ac517e4ac | ||
|
|
e3651367b3 | ||
|
|
02ea41ddd1 | ||
|
|
51ffae4eab | ||
|
|
afe84f37f8 | ||
|
|
0afeef0e00 | ||
|
|
94a17fd97f | ||
|
|
5b5ec55445 | ||
|
|
1e6565c1a5 | ||
|
|
fc522515b9 | ||
|
|
9881b0736d | ||
|
|
e52b4b1466 | ||
|
|
2f45670951 | ||
|
|
50d75ae514 | ||
|
|
dea69a12aa | ||
|
|
e0ce3c12f2 | ||
|
|
93cf516bf1 | ||
|
|
6f4de018af | ||
|
|
6e91cf3172 | ||
|
|
9cb7f8a655 | ||
|
|
5d8d1ad14b | ||
|
|
cac9ca38f6 | ||
|
|
c4523639d5 | ||
|
|
1ce1c6beae | ||
|
|
51d56df7a3 | ||
|
|
860a9a57d6 | ||
|
|
c83e33d608 | ||
|
|
7b80c75d9d | ||
|
|
79337f99ae | ||
|
|
a42ee397f3 | ||
|
|
e58f8bb8c1 | ||
|
|
58cf958e41 | ||
|
|
06d01f7ae4 | ||
|
|
1a33eec0ba | ||
|
|
82de7a1e96 | ||
|
|
8e9bde57c5 | ||
|
|
1bb70e08be | ||
|
|
9afcb7ae61 | ||
|
|
545c4955e6 | ||
|
|
2f2d59b35c | ||
|
|
a1729deed3 | ||
|
|
fc64b97cd5 | ||
|
|
daddc8cb80 | ||
|
|
527c3c7d0d | ||
|
|
fcb4dcaf7c | ||
|
|
3ca4995d34 | ||
|
|
d387f8f06c | ||
|
|
ea43234c86 | ||
|
|
867e56a45e | ||
|
|
a163c63787 | ||
|
|
8389b943d3 | ||
|
|
f2266d9678 | ||
|
|
56bd806978 | ||
|
|
ac7eeea44d | ||
|
|
b741059549 | ||
|
|
cbd984287f | ||
|
|
32e15c3f45 | ||
|
|
f0dc324e35 | ||
|
|
f83c6cf51a | ||
|
|
c068b3ae2f | ||
|
|
adf9dec1e6 | ||
|
|
767d9cbd96 | ||
|
|
e7ccd95c04 | ||
|
|
719f79a8fd | ||
|
|
96f6444958 | ||
|
|
df25f204ba | ||
|
|
8acdc3ede7 | ||
|
|
857b445522 | ||
|
|
5bcca1219a | ||
|
|
4558c26fcd | ||
|
|
a92c6d77dc | ||
|
|
0c95a5ff53 | ||
|
|
cb6d06bb54 | ||
|
|
3ef955c85a | ||
|
|
5e95c16c32 | ||
|
|
4205e2ebcf | ||
|
|
9d806c51c2 | ||
|
|
a38bb31727 | ||
|
|
8a1ef367e2 | ||
|
|
1291865c92 | ||
|
|
a9ebbee7b6 | ||
|
|
06df5ad7d0 | ||
|
|
66b863c989 | ||
|
|
c9efe8e5e1 | ||
|
|
d515223bb5 | ||
|
|
b908f4334b | ||
|
|
6261aba026 | ||
|
|
85bc7534da | ||
|
|
1b30fd1732 | ||
|
|
8c9196bff8 | ||
|
|
b1daf44954 | ||
|
|
11c52d032b | ||
|
|
be291d979d | ||
|
|
6d1edd8d32 | ||
|
|
25ff956c7d | ||
|
|
38179500f8 | ||
|
|
5f7be5f0d6 | ||
|
|
627056febb | ||
|
|
cbd76447fd | ||
|
|
a60a233329 | ||
|
|
a0a3b8ad3e | ||
|
|
d0ae3f5a4d | ||
|
|
6860cf932b | ||
|
|
0276e0805b | ||
|
|
06ff3d8a26 | ||
|
|
1a3b69aa56 | ||
|
|
8237d06ab7 | ||
|
|
1c9f136b57 | ||
|
|
5ab7e4a475 | ||
|
|
3236f358f8 | ||
|
|
4a6550d69a | ||
|
|
ff523d0c67 | ||
|
|
3c93e8eb41 | ||
|
|
88a482fdb9 | ||
|
|
12a9aa7c62 | ||
|
|
50ccf9c585 | ||
|
|
d100eb05a3 | ||
|
|
10d8b5f001 | ||
|
|
ffd3ceb856 | ||
|
|
d942aa9321 | ||
|
|
6469fefe89 | ||
|
|
b082842ee7 | ||
|
|
3573ca0eec | ||
|
|
ad90eb075d | ||
|
|
d55e2d086d | ||
|
|
fe9c966a49 | ||
|
|
9f20afb1a8 | ||
|
|
f61afcfc70 | ||
|
|
961daf8f92 | ||
|
|
64a16cb376 | ||
|
|
ea6b0b2665 | ||
|
|
89df73ac05 | ||
|
|
7d3f3c9983 | ||
|
|
1bdbea2461 | ||
|
|
dfb1f7ccf1 | ||
|
|
b5d1b20727 | ||
|
|
2a407a76be | ||
|
|
d1640a6338 | ||
|
|
26b5c40d95 | ||
|
|
0b3ecf7432 | ||
|
|
8f9bd61505 | ||
|
|
ea28d0ef8a | ||
|
|
4a8c098840 | ||
|
|
ffa4628faa | ||
|
|
e10a9239e1 | ||
|
|
51f7bc924c | ||
|
|
6c0bf79078 | ||
|
|
4b03170920 | ||
|
|
1de6bbc108 | ||
|
|
023ace8e54 | ||
|
|
74d4fcd756 | ||
|
|
9eaa91bfc3 | ||
|
|
484bd75ce4 | ||
|
|
4c30e9602b | ||
|
|
b260d222af | ||
|
|
6528d62cd2 | ||
|
|
b7cf754f6f | ||
|
|
14e3f6ba19 | ||
|
|
a8c1474562 | ||
|
|
8b8a4148ec | ||
|
|
9e147480ed | ||
|
|
4c0aecc685 | ||
|
|
d556b8a5d5 | ||
|
|
e7c0d7b348 | ||
|
|
17360439dc | ||
|
|
9e169a9bea | ||
|
|
305cb79c57 | ||
|
|
141a26f979 | ||
|
|
cfcafdd27c | ||
|
|
f1204a875e | ||
|
|
20295012b8 | ||
|
|
807e82343a | ||
|
|
c8e8f5c204 | ||
|
|
a69b017902 | ||
|
|
e75069f79a | ||
|
|
3f535da79e | ||
|
|
8ebdc364af | ||
|
|
12af2b171d | ||
|
|
04490bf622 | ||
|
|
327bbc92bc | ||
|
|
cc0b4489c7 | ||
|
|
9212ad284f | ||
|
|
503f68dbc4 | ||
|
|
e01e09c712 | ||
|
|
6a6e06fbb0 | ||
|
|
2024f97297 | ||
|
|
25e63f1e56 | ||
|
|
15b60ddf93 | ||
|
|
824461192c | ||
|
|
1eb6cedb03 | ||
|
|
059aded070 | ||
|
|
2d765867c5 | ||
|
|
257ac0c5f7 | ||
|
|
4e96a4be68 | ||
|
|
a2a7e040b1 | ||
|
|
4ded96209e | ||
|
|
f60fea1fb0 | ||
|
|
4d85e409cd | ||
|
|
2bd02d2f59 | ||
|
|
7e194a0a7d | ||
|
|
9beb4d9ea2 | ||
|
|
ab5ebe9507 | ||
|
|
837e8f4eb5 | ||
|
|
e2cb655958 | ||
|
|
8270648da1 | ||
|
|
619000a3c5 | ||
|
|
1c1b925052 | ||
|
|
49bdf1ead9 | ||
|
|
60a3ae19c5 | ||
|
|
951a22165c | ||
|
|
51cdd1a227 | ||
|
|
66adee85be | ||
|
|
4890bcdea2 | ||
|
|
8baf583a3f | ||
|
|
913fa15fb1 | ||
|
|
00fe2f49e0 | ||
|
|
ec2067df75 | ||
|
|
7ddb99d251 | ||
|
|
ba26d3485b | ||
|
|
081a1c4014 | ||
|
|
532246fc9e | ||
|
|
8caf3d7c6c | ||
|
|
d162bee356 | ||
|
|
b43585c34b | ||
|
|
3f60ecd6f0 | ||
|
|
0506a5ed4e | ||
|
|
e7ee1aa093 | ||
|
|
63ed917ad9 | ||
|
|
63e21bdea3 | ||
|
|
1627d577af | ||
|
|
b837c4528d | ||
|
|
46bdfe691a | ||
|
|
dded78b233 | ||
|
|
b594e8defa | ||
|
|
70c50efd0d | ||
|
|
ea3c60ac07 | ||
|
|
fc19399a1f | ||
|
|
980b14f174 | ||
|
|
1df73fe831 | ||
|
|
c125c1dfee | ||
|
|
e39c484ebd | ||
|
|
977a5a2df1 | ||
|
|
02df0007c8 | ||
|
|
b2ed691eb3 | ||
|
|
8d6d5730c9 | ||
|
|
48755ebf09 | ||
|
|
0541a1adf7 | ||
|
|
c992ed4bef | ||
|
|
92025a4113 | ||
|
|
a7d19e917a | ||
|
|
ec1cc455d6 | ||
|
|
ee64582a1f | ||
|
|
425e2405aa | ||
|
|
dea53e6658 | ||
|
|
a9b022ab65 | ||
|
|
c65b77c87f | ||
|
|
8e3a5cba8b | ||
|
|
29ae308398 | ||
|
|
306888afb3 | ||
|
|
f064188032 | ||
|
|
77476580ed | ||
|
|
52ec783613 | ||
|
|
137286e9ba | ||
|
|
79aba0f10a | ||
|
|
515ba97595 | ||
|
|
cd672933c9 | ||
|
|
d9603ef781 | ||
|
|
e40d8bef3b | ||
|
|
ab53883c94 | ||
|
|
6c1e9ac14b | ||
|
|
c7a44c4690 | ||
|
|
2ac4cf0146 | ||
|
|
a914d0aa6a | ||
|
|
91102ad5eb | ||
|
|
378fa56888 | ||
|
|
2a8710ac2f | ||
|
|
66f62650c3 | ||
|
|
18a6bdd541 | ||
|
|
9e732445cf | ||
|
|
7d04e17444 | ||
|
|
34d41475e7 | ||
|
|
0c211c4ec5 | ||
|
|
bf23c8a394 | ||
|
|
f73f7397d7 | ||
|
|
5cee7c2702 | ||
|
|
1aef66bb34 | ||
|
|
4a1c21d62c | ||
|
|
c117675ebd | ||
|
|
6ebdc95754 | ||
|
|
55a22b88c2 | ||
|
|
1fd56c0e33 | ||
|
|
376cb97685 | ||
|
|
84449bf41c | ||
|
|
456a319775 | ||
|
|
157d8cfd6a | ||
|
|
1292e1a557 | ||
|
|
122997da54 | ||
|
|
b59a5c2567 | ||
|
|
2a20cc6da8 | ||
|
|
936bd82755 | ||
|
|
13a58f9590 | ||
|
|
19b0e3bf21 | ||
|
|
203ce0a081 | ||
|
|
e3002bf1a6 | ||
|
|
04db1483d1 | ||
|
|
6fe436a448 | ||
|
|
e710c34469 | ||
|
|
defd6b1d85 | ||
|
|
90d7c6b97d | ||
|
|
e24abf28a2 | ||
|
|
69a0477b74 | ||
|
|
ae7a3b9d2e | ||
|
|
d9f882bea2 | ||
|
|
fef2f1c75e | ||
|
|
5a91334985 | ||
|
|
e198fe833a | ||
|
|
248efe8410 | ||
|
|
dc6a57ffb8 | ||
|
|
240da59f73 | ||
|
|
5a56233f53 | ||
|
|
225accd235 | ||
|
|
ab73a746a0 | ||
|
|
69bc94779c | ||
|
|
3052ce208a | ||
|
|
18e17665fd | ||
|
|
05299fdd5a | ||
|
|
7ef55691a2 | ||
|
|
7509f94fc4 | ||
|
|
343b7b4ad0 | ||
|
|
a2b8220f4e | ||
|
|
5c464ef62e | ||
|
|
5fc639cf9a | ||
|
|
7673013d23 | ||
|
|
c6cc455dd1 | ||
|
|
1da81f7e23 | ||
|
|
ae5b7e04a1 | ||
|
|
305ffb5ef0 | ||
|
|
608aa9fcfc | ||
|
|
c61c7bb225 | ||
|
|
5ed82ae5f2 | ||
|
|
6799320edb | ||
|
|
c406fd60be | ||
|
|
5d514f22a9 | ||
|
|
a066aac332 | ||
|
|
8bd28a87a2 | ||
|
|
065e5bb0b1 | ||
|
|
df6636bff6 | ||
|
|
162e5e0062 | ||
|
|
4219adeeef | ||
|
|
28cfe36e1e | ||
|
|
d2d4990743 | ||
|
|
18eac67c0a | ||
|
|
f8c77edbdf | ||
|
|
4bf62f616b | ||
|
|
9c0d445ef4 | ||
|
|
2896e2485e | ||
|
|
a90f09db4c | ||
|
|
5b99eae59d | ||
|
|
2daca52b80 | ||
|
|
2c594732eb | ||
|
|
cc921df9ce | ||
|
|
ab194ed7ca | ||
|
|
65a01b71bb | ||
|
|
bde46476ee | ||
|
|
e7bfd556c0 | ||
|
|
b683cf37f9 | ||
|
|
3becf468ba | ||
|
|
137e9f878f | ||
|
|
07e25da5bf | ||
|
|
d46ee724fc | ||
|
|
59e470381f | ||
|
|
48d12f14c9 | ||
|
|
122392e0b3 | ||
|
|
3a5a84cdd1 | ||
|
|
24b87607c1 | ||
|
|
6f7812d97b | ||
|
|
cbb5b17ad8 | ||
|
|
cf5984367b | ||
|
|
ee8750451b | ||
|
|
a220545c42 | ||
|
|
a799ca0c63 | ||
|
|
91421cb757 | ||
|
|
53792c934c | ||
|
|
df071825f2 | ||
|
|
e1791f36ea | ||
|
|
0fdf3c1f61 | ||
|
|
ee1df06aab | ||
|
|
1e87eba424 | ||
|
|
08933475ab | ||
|
|
7cbf497da4 | ||
|
|
3a610a007f | ||
|
|
48b090cb5c | ||
|
|
4139298d28 | ||
|
|
51cc10fa54 | ||
|
|
ea6cc33804 | ||
|
|
ad03967ee4 | ||
|
|
f4fd07d303 | ||
|
|
e3c08a34a7 | ||
|
|
118011fe2b | ||
|
|
af3bd07355 | ||
|
|
d68209978a | ||
|
|
47b45b2967 | ||
|
|
2b38e3823b | ||
|
|
282eab7952 | ||
|
|
c346f61535 | ||
|
|
03212e533b | ||
|
|
da8b6517de | ||
|
|
c5db8f93ec | ||
|
|
974a6d087a | ||
|
|
b758b67c37 | ||
|
|
9bafdc62b7 | ||
|
|
97f876b64c | ||
|
|
cbfbd173c4 | ||
|
|
b6f926fbef | ||
|
|
c822620967 | ||
|
|
397c0502e2 | ||
|
|
1682d15a74 | ||
|
|
dd33e98da0 | ||
|
|
c16d966ad3 | ||
|
|
1dfed16071 | ||
|
|
6f835ed6c8 | ||
|
|
9d6fd1727e | ||
|
|
8c1b6a5fd7 | ||
|
|
8dcdb33be9 | ||
|
|
aba8bbb6e3 | ||
|
|
caf4d571e6 | ||
|
|
3b6eb197a8 | ||
|
|
f3e57877ed | ||
|
|
c851c695db | ||
|
|
a3bd7e73d3 | ||
|
|
ab5ceaf74a | ||
|
|
1f2f69d4f6 | ||
|
|
f361b39dea | ||
|
|
eb1fe15ca8 | ||
|
|
45d8a2435e | ||
|
|
706d84fd10 | ||
|
|
a997ca0da0 | ||
|
|
9268b5d677 | ||
|
|
51e4eeeb04 | ||
|
|
05ff659a3c | ||
|
|
db0f488ea8 | ||
|
|
7dcca6c622 | ||
|
|
090856c7e6 | ||
|
|
cc5cc8f1e0 | ||
|
|
c488b68e75 | ||
|
|
1f1873aadd | ||
|
|
0a496f059c | ||
|
|
e27825b0ef | ||
|
|
1f60a18ea1 | ||
|
|
a0088e8364 | ||
|
|
34e26e14c5 | ||
|
|
6b17335209 | ||
|
|
07ed585c38 | ||
|
|
0669ee7a69 | ||
|
|
f84e674d8a | ||
|
|
7f0084316a | ||
|
|
a6918530ce | ||
|
|
4e72fec660 | ||
|
|
4441cf762c | ||
|
|
e83915d10d | ||
|
|
6d37924b86 | ||
|
|
f3d7974e86 | ||
|
|
734d53176f | ||
|
|
9a7be47614 | ||
|
|
26e27d0015 | ||
|
|
94b6878821 | ||
|
|
8b96552f0d | ||
|
|
ae290659de | ||
|
|
6b2b564ac3 | ||
|
|
4f7bb57e97 | ||
|
|
56f0623930 | ||
|
|
f3223fbff6 | ||
|
|
4c4f4c2649 | ||
|
|
773af304ea | ||
|
|
4cc944b0d6 | ||
|
|
87e00feb01 | ||
|
|
e7a4af8903 | ||
|
|
2d69d6146d | ||
|
|
30e4a9441e | ||
|
|
232a8f3569 | ||
|
|
1721453d51 | ||
|
|
499d8dde2b | ||
|
|
6f1cbfd000 | ||
|
|
55ecde7f1b | ||
|
|
6b54d69a85 | ||
|
|
246a31cd73 | ||
|
|
83e4b73596 | ||
|
|
6340ca734f | ||
|
|
baf553db0c | ||
|
|
486bcd5a7b | ||
|
|
be9a74d2f8 | ||
|
|
ffcbc0f011 | ||
|
|
a969ba6e2a | ||
|
|
f1781728af | ||
|
|
cd7df612b1 | ||
|
|
c1a4e257a3 | ||
|
|
4fe6744a22 | ||
|
|
3bd4c47f31 | ||
|
|
98196c4931 | ||
|
|
22cd860124 | ||
|
|
3c973ad92d | ||
|
|
faaf306a63 | ||
|
|
c7e6aea81b | ||
|
|
e541245987 | ||
|
|
84a01bee10 | ||
|
|
d1ced3ae38 | ||
|
|
a6cee69af4 | ||
|
|
0039920ab6 | ||
|
|
39d8550a80 | ||
|
|
ef3d137a64 | ||
|
|
8c707e1e37 | ||
|
|
373e917389 | ||
|
|
74f0f9a042 | ||
|
|
ed6bdb0967 | ||
|
|
c88af046b7 | ||
|
|
ae0187d454 | ||
|
|
0c50e3ddc8 | ||
|
|
075366ad6e | ||
|
|
8e8b2d6f63 | ||
|
|
087eb76140 | ||
|
|
ebedcbaeb8 | ||
|
|
0954a977c9 | ||
|
|
b77efc1948 | ||
|
|
3b0cb34710 | ||
|
|
aa6f832d61 | ||
|
|
ad9c6f06c5 | ||
|
|
a6004d7f17 | ||
|
|
c366717e66 | ||
|
|
22dee512f3 | ||
|
|
6fd5d79e73 | ||
|
|
9d6918d32c | ||
|
|
a49c5c2265 | ||
|
|
30858e3b9b | ||
|
|
30df7efc96 | ||
|
|
3e8c42cba5 | ||
|
|
62cb936cb7 | ||
|
|
39921d03ba | ||
|
|
6a0b00f0d6 | ||
|
|
51eadb692a | ||
|
|
897c113fda | ||
|
|
33e3f1029c | ||
|
|
3d4ff1ba84 | ||
|
|
24036ea507 | ||
|
|
0549c73b7e | ||
|
|
b697fbb7f1 | ||
|
|
96e063c43d | ||
|
|
4e841da1a6 | ||
|
|
09ce307bdb | ||
|
|
a3303e196e | ||
|
|
63437ffbb5 | ||
|
|
69a815aa8f | ||
|
|
1d224949cc | ||
|
|
391f708a09 | ||
|
|
cbd29e5da8 | ||
|
|
50a2841d34 | ||
|
|
9396752c11 | ||
|
|
712dadb287 | ||
|
|
32be32eab8 | ||
|
|
1649f709e7 | ||
|
|
50ca85504c | ||
|
|
4bb68866a8 | ||
|
|
2446514e71 | ||
|
|
109d0e74f1 | ||
|
|
74ea91531a | ||
|
|
9828ab115e | ||
|
|
f77700aa27 | ||
|
|
0fbd980639 | ||
|
|
43cdf1c3d0 | ||
|
|
ff19b1a97d | ||
|
|
1835343acd | ||
|
|
2aaea18f43 | ||
|
|
7ab78b937f | ||
|
|
c7be0164ce | ||
|
|
d203af4a02 | ||
|
|
05f76dab89 | ||
|
|
bf05f8ff20 | ||
|
|
09f3b2cd9c | ||
|
|
22827870fa | ||
|
|
4583dd9e42 | ||
|
|
561441320f | ||
|
|
b2a9c571eb | ||
|
|
efff74c1ae | ||
|
|
a9df0e30b0 | ||
|
|
5ce3e76fbf | ||
|
|
6ec5f5c427 | ||
|
|
5a7212c70e | ||
|
|
3a8b0f6fcc | ||
|
|
a24c31e023 | ||
|
|
f5a3679f1d | ||
|
|
5ac813cb86 | ||
|
|
a93b02e321 | ||
|
|
c77fb9d8f0 | ||
|
|
facc18f2a8 | ||
|
|
bc515b71ec | ||
|
|
7bfa26399b | ||
|
|
461b7b43b4 | ||
|
|
b1cefa57f1 | ||
|
|
ce9a9704c6 | ||
|
|
93a9a55055 | ||
|
|
44eb875a5a | ||
|
|
bc87e609c2 | ||
|
|
005c46d6f5 | ||
|
|
503c609149 | ||
|
|
60704f5e2e | ||
|
|
4e7694d710 | ||
|
|
e33b48700e | ||
|
|
ad59f278c6 | ||
|
|
16f03e7139 | ||
|
|
dc99058d83 | ||
|
|
916959c188 | ||
|
|
864913c0f3 | ||
|
|
13dee6f49e | ||
|
|
62f9c0d470 | ||
|
|
54bb3639d4 | ||
|
|
fca008d8d4 | ||
|
|
43517fcaf5 | ||
|
|
88a77a78ad | ||
|
|
3e2496fb16 | ||
|
|
05da782f8f | ||
|
|
361dfe5158 | ||
|
|
68f6312d4b | ||
|
|
730c6745f0 | ||
|
|
d42d4706bb | ||
|
|
0740e43e20 | ||
|
|
903df07bcb | ||
|
|
0ef1334d78 | ||
|
|
5eb9dde09c | ||
|
|
ae3154aca9 | ||
|
|
3ebe62d1b7 | ||
|
|
f89cae3ecf | ||
|
|
09b768efa4 | ||
|
|
a1d973f987 | ||
|
|
0682b7795c | ||
|
|
b637d7815d | ||
|
|
7ac9ae1125 | ||
|
|
c6af3a32f2 | ||
|
|
16800ea072 | ||
|
|
b5e33ae53a | ||
|
|
3c0c1111fe | ||
|
|
2675f20615 | ||
|
|
e94ad0fa01 | ||
|
|
396750cef5 | ||
|
|
6c45519e18 | ||
|
|
6d95099c56 | ||
|
|
c8328ecde8 | ||
|
|
094bfaeb4f | ||
|
|
bf4e62c19e | ||
|
|
6b1c464d6d | ||
|
|
fa78573778 | ||
|
|
cd2ddb9904 | ||
|
|
9bb3998da4 | ||
|
|
d6dce53e08 | ||
|
|
06093a9a84 | ||
|
|
1d07667ac7 | ||
|
|
591ed1e905 | ||
|
|
907efeb2dc | ||
|
|
beea62cb66 | ||
|
|
5874f3e922 | ||
|
|
04cb536f16 | ||
|
|
8ee8524016 | ||
|
|
ce7845bf54 | ||
|
|
d55f81f5fd | ||
|
|
294d36df47 | ||
|
|
f186bdcbc7 | ||
|
|
ed1bd54b5c | ||
|
|
da2cad4b14 | ||
|
|
0a4a04969d | ||
|
|
45cb8dd9be | ||
|
|
88b09aaddc | ||
|
|
fe71bba356 | ||
|
|
cbc100fc81 | ||
|
|
68bea10bbf | ||
|
|
8628cd603f | ||
|
|
ff325644c7 | ||
|
|
b97026035e | ||
|
|
69cbf78bb6 | ||
|
|
c6cdf6bbee | ||
|
|
09217a1a87 | ||
|
|
332c41e2ff | ||
|
|
2c0c36f54b | ||
|
|
d6b749af91 | ||
|
|
14ffa0770b | ||
|
|
87985855ad | ||
|
|
a2bc254bed | ||
|
|
a7b27e84fa | ||
|
|
529b030228 | ||
|
|
4caa86dd7d | ||
|
|
e1abeeeec2 | ||
|
|
40205a053e | ||
|
|
b8ac466209 | ||
|
|
d1377fa3c4 | ||
|
|
fa79466c2a | ||
|
|
a93bd4b016 | ||
|
|
407a1f3e95 | ||
|
|
4b6af5d53f | ||
|
|
7aa3f9af66 | ||
|
|
f7cf749943 | ||
|
|
aa300f7167 | ||
|
|
c7f3bd2ac8 | ||
|
|
22fe2fd038 | ||
|
|
7480aeffc8 | ||
|
|
bec366b404 | ||
|
|
e06e6e34bf | ||
|
|
832e47beab | ||
|
|
df3d54f776 | ||
|
|
22c0f4fe87 | ||
|
|
9e4cf47ee8 | ||
|
|
fdc97e1383 | ||
|
|
a18bf3149a | ||
|
|
1566bacb2c | ||
|
|
e6e751b066 | ||
|
|
8de875f0fb | ||
|
|
4ace25c5d6 | ||
|
|
1e5051228d | ||
|
|
926332a764 | ||
|
|
d05dd58de1 | ||
|
|
f7443d76f7 | ||
|
|
f344dbc622 | ||
|
|
f4d0c660ca | ||
|
|
1801a29226 | ||
|
|
92be34a407 | ||
|
|
bb58f63ce5 | ||
|
|
367341f745 | ||
|
|
eddf365284 | ||
|
|
a63b8b89e6 | ||
|
|
5757371d43 | ||
|
|
b633de9413 | ||
|
|
c49778df4a | ||
|
|
53a9173fc0 | ||
|
|
d917275e48 | ||
|
|
cc7cb0b893 | ||
|
|
ec0628c4b2 | ||
|
|
97b1d25764 | ||
|
|
33702ab1f8 | ||
|
|
11867dc28c | ||
|
|
d3a8b39c7d | ||
|
|
15379ea1f2 | ||
|
|
efef497b89 | ||
|
|
5aa5f0ff2f | ||
|
|
5bb88f0963 | ||
|
|
1d03016bbc | ||
|
|
ce5732e84f | ||
|
|
a86fdf437e | ||
|
|
3e86d316c4 | ||
|
|
d67ecac59d | ||
|
|
fa14bec83b | ||
|
|
14a4ae883d | ||
|
|
3b799c826d | ||
|
|
b40f26c019 | ||
|
|
dd4ad9ac7e | ||
|
|
2dbba34b2c | ||
|
|
c2bcd1e183 | ||
|
|
d64c81fff7 | ||
|
|
93be5b1e02 | ||
|
|
9a31b68b59 | ||
|
|
0007ee9064 | ||
|
|
67ab3285b5 | ||
|
|
41a8d9e99b | ||
|
|
90477fb794 | ||
|
|
98079ea898 | ||
|
|
4790115455 | ||
|
|
27b78d990b | ||
|
|
77607cbea0 | ||
|
|
102208df69 | ||
|
|
6de81f1250 | ||
|
|
20fd11e11a | ||
|
|
9cdcfe9f19 | ||
|
|
5e3e464ac4 | ||
|
|
3a3965ac21 | ||
|
|
a7369bef8a | ||
|
|
d2aa7dfbb6 | ||
|
|
63ec5d1264 | ||
|
|
f6381cf482 | ||
|
|
34b5d19488 | ||
|
|
d6cb7e4815 | ||
|
|
d389e0191b | ||
|
|
d3699bb6bc | ||
|
|
13480e8c2a | ||
|
|
5b3b93f80a | ||
|
|
b69e845b1c | ||
|
|
90c3822bfa | ||
|
|
c895a0626d | ||
|
|
b842bc97bb | ||
|
|
0f38fa05a6 | ||
|
|
45c5cb1f8f | ||
|
|
f6d6956261 | ||
|
|
60176c7bf4 | ||
|
|
362c9303da | ||
|
|
5e95a552ee | ||
|
|
90cb222551 | ||
|
|
850163288d | ||
|
|
e3ec6f0bd7 | ||
|
|
f7bfbdc872 | ||
|
|
4918bd5505 | ||
|
|
9bad339af8 | ||
|
|
ba4fc0f996 | ||
|
|
2fd5bc952d | ||
|
|
0ddb8769bb | ||
|
|
654f59e762 | ||
|
|
d91b1fd402 | ||
|
|
c6d82c9ba6 | ||
|
|
4d25cf89d5 | ||
|
|
24e9207e13 | ||
|
|
89130d91d6 | ||
|
|
d644b2a17d | ||
|
|
bd7bfa21c4 | ||
|
|
403de05925 | ||
|
|
46c89f2bd0 | ||
|
|
23facf0d77 | ||
|
|
549b1a478c | ||
|
|
7f8565b94c | ||
|
|
06568c6636 | ||
|
|
5d07d77e75 | ||
|
|
62018e1f72 | ||
|
|
7c0f2543a7 | ||
|
|
ca85a28241 | ||
|
|
585840b033 | ||
|
|
dec180ac00 | ||
|
|
86fa104692 | ||
|
|
b059c96dc6 | ||
|
|
a77cec8d58 | ||
|
|
64bcff1c7c | ||
|
|
2ed162ac20 | ||
|
|
e66b4dff3c | ||
|
|
8efd731cc4 | ||
|
|
a5ae1f8587 | ||
|
|
b8f16556d3 | ||
|
|
cbe379ad6b | ||
|
|
338b340be9 | ||
|
|
a006eb7e14 | ||
|
|
554b580e97 | ||
|
|
0df29f5e23 | ||
|
|
b4c0f092d8 | ||
|
|
78c6184752 | ||
|
|
38440b204d | ||
|
|
ad4a8ff7d9 | ||
|
|
04b0ac0537 | ||
|
|
982faf4024 | ||
|
|
fe3992f9fa | ||
|
|
7aa970e2c7 | ||
|
|
30d0879ed5 | ||
|
|
fd6ad9e481 | ||
|
|
794fccca7f | ||
|
|
394ff492da | ||
|
|
1e153945de | ||
|
|
0b8a5a30a7 | ||
|
|
150162bc37 | ||
|
|
8805283088 | ||
|
|
65c7212000 | ||
|
|
979fe86bc8 | ||
|
|
ff841ebf5a | ||
|
|
360f2513ab | ||
|
|
4c960fa90a | ||
|
|
9003b50b13 | ||
|
|
f6e62e2af9 | ||
|
|
47b9ac59c7 | ||
|
|
0705a7e2d5 | ||
|
|
28b879ac47 | ||
|
|
caeea190f1 | ||
|
|
8ff70de618 | ||
|
|
ee4d1cea92 | ||
|
|
f4f400776b | ||
|
|
b467a454b4 | ||
|
|
efb8b5566a | ||
|
|
f9c863708c | ||
|
|
2941d3ac89 | ||
|
|
d36b732c4c | ||
|
|
d2c5458e31 | ||
|
|
8d8a54ec79 | ||
|
|
1062667618 | ||
|
|
6ef15b34ca | ||
|
|
3d04f46334 | ||
|
|
aff3396280 | ||
|
|
70d1873dd9 | ||
|
|
0491805d2f | ||
|
|
61b838dd57 | ||
|
|
fbf01f7046 | ||
|
|
5f4dc5c6ca | ||
|
|
2ae195f5a7 | ||
|
|
393415597c | ||
|
|
ae4624bf46 | ||
|
|
5e321739db | ||
|
|
9f79ee4ae3 | ||
|
|
28de38768e | ||
|
|
25cf5e373e | ||
|
|
424c4a8a53 | ||
|
|
97e618a0e3 | ||
|
|
d8dbd903d0 | ||
|
|
81c538efce | ||
|
|
d310ab7ecb | ||
|
|
0b1008d367 | ||
|
|
32fc6dbe03 | ||
|
|
83d2ed09fc | ||
|
|
fbc5205702 | ||
|
|
cbc6524234 | ||
|
|
094b5c3d90 | ||
|
|
3267804598 | ||
|
|
476693678e | ||
|
|
bd9520b7ad | ||
|
|
3ad3f3bbd4 | ||
|
|
ad946d555d | ||
|
|
800c5cc1e7 | ||
|
|
857973e6f7 | ||
|
|
9c448c8018 | ||
|
|
193de4abf5 | ||
|
|
98906275a0 | ||
|
|
b9ff5c8f43 | ||
|
|
3d9d2dd001 | ||
|
|
17b475912f | ||
|
|
e9828b6f66 | ||
|
|
72eba2bffc | ||
|
|
6ac3bc0452 | ||
|
|
00cd9d5519 | ||
|
|
f2658275b2 | ||
|
|
25e27235dd | ||
|
|
bf2db4b084 | ||
|
|
5782649ad9 | ||
|
|
288df49c96 | ||
|
|
10cfc0ddb3 | ||
|
|
15b1b7e9c3 | ||
|
|
00c0f69aa5 | ||
|
|
51943369e3 | ||
|
|
2d75f2e4a5 | ||
|
|
976afc93e4 | ||
|
|
7f68f82146 | ||
|
|
85900a246c | ||
|
|
b4f971a081 | ||
|
|
3e1551a1de | ||
|
|
af292dae6d | ||
|
|
933878f2c8 | ||
|
|
d54409dcd3 | ||
|
|
5bf50af2d0 | ||
|
|
c43b8a6326 | ||
|
|
b06900d1a3 | ||
|
|
f2f02fc3fb | ||
|
|
aaeea9f6ed | ||
|
|
2bb6f7735f | ||
|
|
40766e55e8 | ||
|
|
b5ea1cc255 | ||
|
|
6d8e8ac0fa | ||
|
|
24b167ada8 | ||
|
|
993f8cbb1b | ||
|
|
47a9516980 | ||
|
|
dc8a1b1bcf | ||
|
|
cdb755c5f1 | ||
|
|
063efb330a | ||
|
|
70772c9091 | ||
|
|
10d8540f62 | ||
|
|
006c162382 | ||
|
|
6799a46605 | ||
|
|
c4638f9e66 | ||
|
|
4b34f5d22f | ||
|
|
a0358e5ddb | ||
|
|
a03f8d4c37 | ||
|
|
c4a0937683 | ||
|
|
2f4c4b6076 | ||
|
|
a008a843cf | ||
|
|
d92c53e700 | ||
|
|
a754e1d7b2 | ||
|
|
8e9ffba66e | ||
|
|
15a97ad6fb | ||
|
|
91f4a5e4b5 | ||
|
|
0fa7e62947 | ||
|
|
62f992f06c | ||
|
|
a23949d44d | ||
|
|
b692f23466 | ||
|
|
8aa999ef69 | ||
|
|
20b215f293 | ||
|
|
e6096e643a | ||
|
|
8938ae05ac | ||
|
|
9d1b22aac2 | ||
|
|
1fc02680af | ||
|
|
4872aa747b | ||
|
|
7ea3d3fdca | ||
|
|
50f86ce8e4 | ||
|
|
7e22cf28f8 | ||
|
|
3b1b3e9d50 | ||
|
|
ab72091de2 | ||
|
|
66f57867d8 | ||
|
|
6375838445 | ||
|
|
82a14af5e7 | ||
|
|
97dce08ed7 | ||
|
|
198d940af6 | ||
|
|
1d7e0a36e3 | ||
|
|
10068600f8 | ||
|
|
b7639d5815 | ||
|
|
49752b90d5 | ||
|
|
e98bd52e25 | ||
|
|
8a8bbad0cf | ||
|
|
fec216df32 | ||
|
|
4e1fe44428 | ||
|
|
51967f9807 | ||
|
|
b37f8b99ae | ||
|
|
fc2833f172 | ||
|
|
490f90758d | ||
|
|
56618c31f6 | ||
|
|
604f7598c2 | ||
|
|
2a7a2b84ec | ||
|
|
3e21a1a6fa | ||
|
|
2b29191e7c | ||
|
|
03431d6373 | ||
|
|
cc1a29e250 | ||
|
|
e62e9b6187 | ||
|
|
19c51cfa49 | ||
|
|
d5082158ee | ||
|
|
3f7483e816 | ||
|
|
0c8584eabc | ||
|
|
f00690f93e | ||
|
|
89b12ed35b | ||
|
|
1a9a3489ec | ||
|
|
c8a80487cd | ||
|
|
4ea8e80dd9 | ||
|
|
c07d30dcb1 | ||
|
|
d588ab54d4 | ||
|
|
f8b422a7b6 | ||
|
|
29fe922b14 | ||
|
|
8707019237 | ||
|
|
d1fbb77e0f | ||
|
|
1fbe4d2f5f | ||
|
|
0575610fa1 | ||
|
|
e3f1455850 | ||
|
|
bd9b3cf55b | ||
|
|
14db4212ab | ||
|
|
00a5b5d477 | ||
|
|
b8eac19177 | ||
|
|
b47b04c846 | ||
|
|
613ad15d02 | ||
|
|
24187530fb | ||
|
|
a857daa351 | ||
|
|
f01d7be6c6 | ||
|
|
d387380a25 | ||
|
|
f2e4c277c4 | ||
|
|
5107ace14a | ||
|
|
7b1eae4f50 | ||
|
|
c152dc8492 | ||
|
|
7bcca0060f | ||
|
|
d68c2ca2b7 | ||
|
|
de73a497ca | ||
|
|
e3ec15af10 | ||
|
|
dac74312da | ||
|
|
2ecd9bd5c0 | ||
|
|
a0ab18f6eb | ||
|
|
ebe95a831f | ||
|
|
ee4158678a | ||
|
|
83349b8aa4 | ||
|
|
7fa836e105 | ||
|
|
1633e30834 | ||
|
|
c8ca33f810 | ||
|
|
e243c072b5 | ||
|
|
da4f372271 | ||
|
|
610e782a29 | ||
|
|
854cf26907 | ||
|
|
bb201c211a | ||
|
|
12fae49fff | ||
|
|
fd372273bd | ||
|
|
b98d22c191 | ||
|
|
160f6507c3 | ||
|
|
613d6c5249 | ||
|
|
81a883fda3 | ||
|
|
40b695c1f1 | ||
|
|
5f938534a9 | ||
|
|
8d718cbb3e | ||
|
|
f6a2b79310 | ||
|
|
82e3f45a9f | ||
|
|
072e81b3c5 | ||
|
|
1d97ac4fd2 | ||
|
|
db73746620 | ||
|
|
97bc798b05 | ||
|
|
edc231bc58 | ||
|
|
b85e092e23 | ||
|
|
583043f527 | ||
|
|
8f6213cce9 | ||
|
|
00ec693db8 | ||
|
|
70b4a818ef | ||
|
|
7c28612a59 | ||
|
|
6f4681034e | ||
|
|
6938f3476e | ||
|
|
17fb9ea763 | ||
|
|
7d23a66ff0 | ||
|
|
703c7ff429 | ||
|
|
8a9be9e493 | ||
|
|
c92f0083a2 | ||
|
|
b5dbfd142a | ||
|
|
cbf13a2a6d | ||
|
|
5b3bf92101 | ||
|
|
0744ca66ad | ||
|
|
2d33bda2e6 | ||
|
|
32f90c0fad | ||
|
|
bce6e1bc6d | ||
|
|
824202ef54 | ||
|
|
9ebfca1e84 | ||
|
|
6429e421b3 | ||
|
|
c9bfa948c3 | ||
|
|
e7829aefd8 | ||
|
|
51ea3ca254 | ||
|
|
57ab36e77d | ||
|
|
dd0e0a3995 | ||
|
|
6fd6dacb39 | ||
|
|
39048ad10b | ||
|
|
979cdf9b64 | ||
|
|
dbf721235b | ||
|
|
c979fa04a4 | ||
|
|
c5f4ec7d23 | ||
|
|
5d3b87a484 | ||
|
|
72ae2f3d56 | ||
|
|
6c0cb858c1 | ||
|
|
e0c0ad3b5e | ||
|
|
4619d94622 | ||
|
|
0975a58e9b | ||
|
|
a25720a34a | ||
|
|
cc111e0bab | ||
|
|
86bec2d399 | ||
|
|
a59ff5f3df | ||
|
|
c3a04081ff | ||
|
|
ae76242fdf | ||
|
|
4f04476e3b | ||
|
|
1486a9c7f2 | ||
|
|
5ada888507 | ||
|
|
5f8e58f49b | ||
|
|
b8071a849a | ||
|
|
b6e9e7c32d | ||
|
|
0435d041ea | ||
|
|
795501bc86 | ||
|
|
c2207688c0 | ||
|
|
98c098bfc7 | ||
|
|
c47e3ba446 | ||
|
|
f1668d2786 | ||
|
|
7d7b7b31e5 | ||
|
|
3ddacb86e9 | ||
|
|
60b68069cf | ||
|
|
871417d45d | ||
|
|
65d1e3bb9b | ||
|
|
0fc2f31368 | ||
|
|
c3e0b9b6e7 | ||
|
|
6ea1f23b3f | ||
|
|
963c380d13 | ||
|
|
00238fb019 | ||
|
|
74e6b52011 | ||
|
|
875b8160f6 | ||
|
|
76ff440ebe | ||
|
|
8db957dfbf | ||
|
|
9d633048fe | ||
|
|
a9b55837dc | ||
|
|
c352dd8f1a | ||
|
|
3a2371527f | ||
|
|
1ee9be4c3f | ||
|
|
56ad6c9be1 | ||
|
|
fa04c83d86 | ||
|
|
4c82efc5ac | ||
|
|
5f45d6a715 | ||
|
|
2329bef5ba | ||
|
|
62ab3ccd3d | ||
|
|
71aaa5a791 | ||
|
|
08619211f8 | ||
|
|
3dffbc3ebf | ||
|
|
0d6eb134f5 | ||
|
|
50db3492e2 | ||
|
|
3b19596122 | ||
|
|
d082faf3e4 | ||
|
|
99e8891f85 | ||
|
|
532066ee2d | ||
|
|
254390644a | ||
|
|
241fa9c6c8 | ||
|
|
e142a83296 | ||
|
|
f7029f5c08 | ||
|
|
c50f25a3ea | ||
|
|
65c9b48921 | ||
|
|
f25e6c6d33 | ||
|
|
587ad4f271 | ||
|
|
4452292064 | ||
|
|
e597dba7ec | ||
|
|
dd9d9ce54c | ||
|
|
06e54b823e | ||
|
|
32b4e4cb7c | ||
|
|
376d48c7f1 | ||
|
|
6586e8352a | ||
|
|
3511a92869 | ||
|
|
44de649e5c | ||
|
|
29c122af83 | ||
|
|
6dbdc972c4 | ||
|
|
7b174c250d | ||
|
|
50d7f721ee | ||
|
|
5a4120dbfb | ||
|
|
eec5c1e21c | ||
|
|
1f776a4aa2 | ||
|
|
227ddad9b5 | ||
|
|
a9bf81ad91 | ||
|
|
6008bdbbc1 | ||
|
|
93bafe619d | ||
|
|
8ab91e9f7f | ||
|
|
5731050062 | ||
|
|
fb63dd1345 | ||
|
|
5f8002fcd7 | ||
|
|
19b1689161 | ||
|
|
b485ed97aa | ||
|
|
53c4c5c859 | ||
|
|
dc27e148a1 | ||
|
|
45cca58592 | ||
|
|
e136725c5b | ||
|
|
486479e943 | ||
|
|
3bb51da835 | ||
|
|
806cf78797 | ||
|
|
3b3f441189 | ||
|
|
24b5a5d50b | ||
|
|
d56a604a96 | ||
|
|
8c0b73d3a8 | ||
|
|
6bd3a09fb8 | ||
|
|
f65b0e546b | ||
|
|
8584c502d3 | ||
|
|
c3edf383ff | ||
|
|
c4cd95df68 | ||
|
|
ed4c0767b1 | ||
|
|
043c271f8a | ||
|
|
d4da20f064 | ||
|
|
903650af67 | ||
|
|
ef1d7425e3 | ||
|
|
1d1c795601 | ||
|
|
889d8a156f | ||
|
|
b7f666ff09 | ||
|
|
e4e9b342a7 | ||
|
|
d5c35a59b0 | ||
|
|
2f9fd1dcc5 | ||
|
|
8f3194f7ac | ||
|
|
10bd29265b | ||
|
|
42b44a591b | ||
|
|
a810559b24 | ||
|
|
861c89141a | ||
|
|
8939c95fd6 | ||
|
|
408c368fa5 | ||
|
|
b5d9a362b4 | ||
|
|
f1af2bb485 | ||
|
|
1b55190d3f | ||
|
|
f373a15b62 | ||
|
|
91543f4831 | ||
|
|
d81b42d067 | ||
|
|
724789de13 | ||
|
|
8f51a29137 | ||
|
|
c845f6eda5 | ||
|
|
89500e31f1 | ||
|
|
c8f2dd8b53 | ||
|
|
ceae52df15 | ||
|
|
c2d8d3ffc4 | ||
|
|
aa985beeef | ||
|
|
65e7912d31 | ||
|
|
02ed24d351 | ||
|
|
6acef73052 | ||
|
|
10ae7b50f2 | ||
|
|
831b5ba12b | ||
|
|
0932f9c08b | ||
|
|
397542b213 | ||
|
|
0c38719fe0 | ||
|
|
ff7eea27e7 | ||
|
|
687bac22db | ||
|
|
8d41ebd8a3 | ||
|
|
4631dbf68c | ||
|
|
4f9aefc753 | ||
|
|
4b5287005f | ||
|
|
5c32841934 | ||
|
|
ccd1d32c3a | ||
|
|
75ffc9bf15 | ||
|
|
3af1ea8cbc | ||
|
|
1f0dc5835b | ||
|
|
ed1fc98595 | ||
|
|
b58fb39f24 | ||
|
|
0304d28f7e | ||
|
|
f5adbb90a1 | ||
|
|
32b826e2a0 | ||
|
|
0937692dc6 | ||
|
|
785ee80b93 | ||
|
|
f119ed382e | ||
|
|
da23c4f960 | ||
|
|
4885d57c58 | ||
|
|
0db0e0c216 | ||
|
|
ec2962eacb | ||
|
|
0ca895f585 | ||
|
|
6299ffbe60 | ||
|
|
7f0485cf53 | ||
|
|
02bff4f109 | ||
|
|
d1ca25ca7e | ||
|
|
23c2176681 | ||
|
|
e83297d0f6 | ||
|
|
41de7442d2 | ||
|
|
0852d76b58 | ||
|
|
a55ce08cc0 | ||
|
|
dd090561bf | ||
|
|
28f04fd647 | ||
|
|
50a96b62f1 | ||
|
|
00b963ab72 | ||
|
|
79333a2498 | ||
|
|
32f82c62c8 | ||
|
|
4e076d746f | ||
|
|
13e435ebca | ||
|
|
4b0eecbb44 | ||
|
|
0360a524df | ||
|
|
262ac85107 | ||
|
|
4c70046d93 | ||
|
|
458824dcb4 | ||
|
|
a7338645d7 | ||
|
|
776fd04754 | ||
|
|
20bccd499f | ||
|
|
708bcd2dd3 | ||
|
|
d0edff7d6e | ||
|
|
ccca70cb33 | ||
|
|
0d829ebc69 | ||
|
|
4137b84e4e | ||
|
|
e6c2a670fe | ||
|
|
47f99dd2b3 | ||
|
|
6759b99e28 | ||
|
|
3471f18130 | ||
|
|
2ef843dd16 | ||
|
|
ce2a0f5a6a | ||
|
|
adca3e9c4b | ||
|
|
366dfcb907 | ||
|
|
28c625572b | ||
|
|
02f9b76418 | ||
|
|
ba8badd6df | ||
|
|
0decc869ae | ||
|
|
b573aebc09 | ||
|
|
d31d057aa3 | ||
|
|
6445c8ed73 | ||
|
|
382e38f494 | ||
|
|
9940aba9f6 | ||
|
|
7e846b9858 | ||
|
|
d322de0613 | ||
|
|
b98f771519 | ||
|
|
c7a93f6e4e | ||
|
|
970ce22b68 | ||
|
|
e292e93d35 | ||
|
|
fa164d459f | ||
|
|
f53c79c01b | ||
|
|
7dbe193bee | ||
|
|
a669f012dd | ||
|
|
237724c0c7 | ||
|
|
53f84c7f62 | ||
|
|
6692a1a53f | ||
|
|
a37cd7aaf5 | ||
|
|
e4cdbbf521 | ||
|
|
4568a6f842 | ||
|
|
5c72bb9e33 | ||
|
|
8c3bdb4ffc | ||
|
|
ffbad34b31 | ||
|
|
f086d39641 | ||
|
|
cc4baaab0d | ||
|
|
66409193dc | ||
|
|
2937f8a040 | ||
|
|
edf0bde0c6 | ||
|
|
8d03046269 | ||
|
|
9f48ffa1e8 | ||
|
|
871d4562f1 | ||
|
|
0f371f9e1a | ||
|
|
6bd109aa2f | ||
|
|
f7a40ec650 | ||
|
|
ff1b41dc57 | ||
|
|
fc4c4fda05 | ||
|
|
ef1a94abaa | ||
|
|
d9fb0be8c7 | ||
|
|
3f3adae6bc | ||
|
|
1ecbaaa382 | ||
|
|
d859ca2f9b | ||
|
|
3953dcc7f2 | ||
|
|
625ac28c61 | ||
|
|
b4b9308079 | ||
|
|
e2ba0df2d4 | ||
|
|
921360ce62 | ||
|
|
429805dbbc | ||
|
|
0da5e8979b | ||
|
|
baa80ae512 | ||
|
|
3e8ed78bf1 | ||
|
|
48493329d6 | ||
|
|
76dd75de77 | ||
|
|
63fd27e35f | ||
|
|
115ac3e4d7 | ||
|
|
cfcad42ff1 | ||
|
|
3f2873d42c | ||
|
|
ab915f837c | ||
|
|
ddd9a6b499 | ||
|
|
7abb69b5dc | ||
|
|
d5052fb24f | ||
|
|
b5a7ff42bb | ||
|
|
48fd1c4dd6 | ||
|
|
2bb73af7d1 | ||
|
|
86e92f9983 | ||
|
|
1c10b9de11 | ||
|
|
a66d36ea11 | ||
|
|
aa63a21ce0 | ||
|
|
797a7afba4 | ||
|
|
4b5ea12e90 | ||
|
|
2b6390fdc9 | ||
|
|
bd08ae67f9 | ||
|
|
4582c0efe7 | ||
|
|
834f36fe6d | ||
|
|
6f130def07 | ||
|
|
3931a7bd85 | ||
|
|
d9ee9c0872 | ||
|
|
0b0a73c1c9 | ||
|
|
81925ab73a | ||
|
|
9de1aa9b7f | ||
|
|
6f9aaa93e9 | ||
|
|
7e5664bdbc | ||
|
|
83f28bef6c | ||
|
|
96c727fda6 | ||
|
|
49dc570a72 | ||
|
|
cd1e04a234 | ||
|
|
27cb314e54 | ||
|
|
56a1142f03 | ||
|
|
5b37aa8c19 | ||
|
|
8ac9787350 | ||
|
|
9f9bd08af8 | ||
|
|
4c985dac39 | ||
|
|
3d77c0460d | ||
|
|
3ddad24608 | ||
|
|
6e37ab595c | ||
|
|
a1a79edaea | ||
|
|
49333cbdbe | ||
|
|
de92b479d9 | ||
|
|
0f128eb58c | ||
|
|
c630924d66 | ||
|
|
ff59fc82b3 | ||
|
|
52a1ae72f0 | ||
|
|
3a654c506f | ||
|
|
2763d4b51a | ||
|
|
e28836bf45 | ||
|
|
a6ebfacf7b | ||
|
|
c7961075c4 | ||
|
|
ab6ede7e04 | ||
|
|
b3538f1100 | ||
|
|
3b323bda58 | ||
|
|
13d86c7372 | ||
|
|
208fb610a6 | ||
|
|
4038ae2005 | ||
|
|
dd1721c799 | ||
|
|
a21e27bc99 | ||
|
|
b0ff858e78 | ||
|
|
54dae552b1 | ||
|
|
25c4198f7c | ||
|
|
4ead40cf67 | ||
|
|
04a0612e8a | ||
|
|
aa608c84b4 | ||
|
|
38365ff040 | ||
|
|
9c4270bcd9 | ||
|
|
46b066565e | ||
|
|
4dc9c657ad | ||
|
|
39595cfe31 | ||
|
|
ffa3d7d6a2 | ||
|
|
aa67fe7a8c | ||
|
|
bb2509fd2c | ||
|
|
61744359de | ||
|
|
095f62551f | ||
|
|
e25db1f273 | ||
|
|
79cb46c0e9 | ||
|
|
22ce550e53 | ||
|
|
30393100c1 | ||
|
|
459380965a | ||
|
|
21bac1bccd | ||
|
|
b1a1b6def5 | ||
|
|
baeb3adf21 | ||
|
|
39f6a04ca4 | ||
|
|
37c9ccebd1 | ||
|
|
71c73ac17c | ||
|
|
c6cb7407b3 | ||
|
|
333b2ceb97 | ||
|
|
b456b9fdfe | ||
|
|
34d0a36a1d | ||
|
|
355736f36f | ||
|
|
771287be11 | ||
|
|
dc9476b670 | ||
|
|
1e14cc0f48 | ||
|
|
55b548ae2b | ||
|
|
3b43646a08 | ||
|
|
3bc0d932d0 | ||
|
|
60225f4e75 | ||
|
|
1962446269 | ||
|
|
be37986a0f | ||
|
|
d7346a1e8c | ||
|
|
87d346f6a7 | ||
|
|
f0dd7f807d | ||
|
|
0c0502426f | ||
|
|
7f035f58c6 | ||
|
|
81e84f8dac | ||
|
|
55b42f6de3 | ||
|
|
ed8b68ad06 | ||
|
|
bad7b875eb | ||
|
|
5d162f20a9 | ||
|
|
9d29949440 | ||
|
|
1b75c1e61f | ||
|
|
293fd0f700 | ||
|
|
c1be917782 | ||
|
|
bb86e858b6 | ||
|
|
8445f5d2e2 | ||
|
|
72c9c3b11b | ||
|
|
6e3dba3fde | ||
|
|
7558ecd9ac | ||
|
|
1f776932a1 | ||
|
|
4820dce97a | ||
|
|
f8abe0c566 | ||
|
|
9def963c65 | ||
|
|
990123a937 | ||
|
|
1d6c639310 | ||
|
|
429798fd08 | ||
|
|
b5a8dd1dec | ||
|
|
95a0bd3701 | ||
|
|
8ff556739e | ||
|
|
496787677e | ||
|
|
e1ff419cf9 | ||
|
|
ee86ce68fc | ||
|
|
b75e936372 | ||
|
|
aa79235194 | ||
|
|
7c305be1bd | ||
|
|
f7fe362721 | ||
|
|
36bec089f7 | ||
|
|
45dd1fece4 | ||
|
|
29d28dda95 | ||
|
|
421594f83d | ||
|
|
d89fb4ed4f | ||
|
|
295a54eed3 | ||
|
|
5c0bd5b112 | ||
|
|
86e3b9a026 | ||
|
|
2f38141f43 | ||
|
|
8273ea5a19 | ||
|
|
4f7b304f53 | ||
|
|
8e4b87918f | ||
|
|
83b2198e86 | ||
|
|
d1a5975f9b | ||
|
|
52002051ad | ||
|
|
b191a77901 | ||
|
|
23780dd577 | ||
|
|
d1e9a582ad | ||
|
|
819ff4dd0f | ||
|
|
de604c18a0 | ||
|
|
be6cfb42ab | ||
|
|
2022310f95 | ||
|
|
657ed09693 | ||
|
|
c99df938d7 | ||
|
|
cf568a3726 | ||
|
|
e4807d8bb2 | ||
|
|
35239a302a | ||
|
|
db3946c358 | ||
|
|
0d28af84d0 | ||
|
|
42698cb7ab | ||
|
|
1d860415f2 | ||
|
|
289a253569 | ||
|
|
faafb3f7b7 | ||
|
|
2b127a1eab | ||
|
|
dfb23b3f77 | ||
|
|
b269221c00 | ||
|
|
8b46061e73 | ||
|
|
4d0f5b4c44 | ||
|
|
1dedeb87cc | ||
|
|
79cfefd856 | ||
|
|
0c0d4793ac | ||
|
|
12d71ed28c | ||
|
|
9fed0f71c2 | ||
|
|
2e34ac1403 | ||
|
|
bc54ae392b | ||
|
|
00acd06340 | ||
|
|
476e4a03c1 | ||
|
|
5f11b3e5e0 | ||
|
|
3169daad46 | ||
|
|
fd05f12790 | ||
|
|
ad094275b0 | ||
|
|
c740e4f342 | ||
|
|
132255b5da | ||
|
|
c4c0488ac6 | ||
|
|
a2ce6fcc91 | ||
|
|
12090548d2 | ||
|
|
8223cb15e7 | ||
|
|
4ba9b38cc5 | ||
|
|
42243214b5 | ||
|
|
23245c0cb2 | ||
|
|
b271446f82 | ||
|
|
611ebc5f1e | ||
|
|
be0f45cdbc | ||
|
|
9b40cbf587 | ||
|
|
c4a7f90ebb | ||
|
|
9609baee41 | ||
|
|
395eb71931 | ||
|
|
8bc4cecee6 | ||
|
|
6b617c0d15 | ||
|
|
55d290a3bf | ||
|
|
e17b4b3871 | ||
|
|
236e072cab | ||
|
|
05ff1ed7cc | ||
|
|
2b5bae9a8f | ||
|
|
39f1b8e73d | ||
|
|
af576b56c2 | ||
|
|
54dd393f39 | ||
|
|
4ce4f3779b | ||
|
|
8b3ae2fd43 | ||
|
|
ed55cb66e6 | ||
|
|
2cd9a0de1f | ||
|
|
c514ab9907 | ||
|
|
078a630bba | ||
|
|
43c271b07c | ||
|
|
24ce681e51 | ||
|
|
5ae34bf3c8 | ||
|
|
51931b888a | ||
|
|
9f7f3b1216 | ||
|
|
97c83bb05b | ||
|
|
8767ceecd4 | ||
|
|
18c63eff8f | ||
|
|
c64b7f6a78 | ||
|
|
068b4b51e3 | ||
|
|
919dd7cf14 | ||
|
|
f632e56793 | ||
|
|
2021c66251 | ||
|
|
8358e0f4b2 | ||
|
|
7f61b3ad59 | ||
|
|
a9ab732e35 | ||
|
|
11263a462c | ||
|
|
231d061b45 | ||
|
|
cdbee9a40b | ||
|
|
7b4ad2eb34 | ||
|
|
19d69be220 | ||
|
|
04363607aa | ||
|
|
dcffad2a86 | ||
|
|
6a69ab5ebd | ||
|
|
fc92ead0dd | ||
|
|
61ce600b20 | ||
|
|
7a14dfebbb | ||
|
|
42fb8153ba | ||
|
|
6f13e53886 | ||
|
|
d1c759c5c1 | ||
|
|
e46164e0bd | ||
|
|
7389ce7ff5 | ||
|
|
2f77797b17 | ||
|
|
9380ba70d6 | ||
|
|
1023dcbc9e | ||
|
|
83e854e359 | ||
|
|
50303b19d8 | ||
|
|
89382bacaa | ||
|
|
6c559c34df | ||
|
|
adaa6888dd | ||
|
|
a813111379 | ||
|
|
18f0fb050b | ||
|
|
05e92e5afe | ||
|
|
4723d49dad | ||
|
|
fbbc14541a | ||
|
|
5ef33279f2 | ||
|
|
1e02a85970 | ||
|
|
0e88d53faa | ||
|
|
01d1b8ddf2 | ||
|
|
c8257540bc | ||
|
|
2240704863 | ||
|
|
e8ca69ea16 | ||
|
|
da632e7cc1 | ||
|
|
30cd96663f | ||
|
|
7dbe98147d | ||
|
|
5d71d83420 | ||
|
|
38a59a9ff7 | ||
|
|
4b028ad612 | ||
|
|
442560beb4 | ||
|
|
7d2b5c9583 | ||
|
|
29689cfa5a | ||
|
|
52d4abf2f9 | ||
|
|
a953096485 | ||
|
|
884a6dfe6d | ||
|
|
0068301d24 | ||
|
|
353ae4d270 | ||
|
|
e759d426fa | ||
|
|
40ef23b547 | ||
|
|
f5e8562f96 | ||
|
|
1567feae3c | ||
|
|
daf061c9de | ||
|
|
d0e2c6c9ab | ||
|
|
8643ec7fea | ||
|
|
5cfea3d402 | ||
|
|
6c8f21e4a4 | ||
|
|
1d0f91c4a9 | ||
|
|
2a82db4caf | ||
|
|
dd88c17f15 | ||
|
|
8b37270410 | ||
|
|
760169fc43 | ||
|
|
7023e38294 | ||
|
|
a7cf58cc47 | ||
|
|
e25d1a2ea2 | ||
|
|
70969c1757 | ||
|
|
3803437dcc | ||
|
|
eabc6dd76a | ||
|
|
e28d2e2b77 | ||
|
|
96fafe2ed6 | ||
|
|
c81d390f84 | ||
|
|
08456c61f6 | ||
|
|
bc26f9a03f | ||
|
|
6ffeff86be | ||
|
|
f444cddbaf | ||
|
|
d13191a46c | ||
|
|
801ca9a7b7 | ||
|
|
df66e341de | ||
|
|
71ee7ee254 | ||
|
|
a156cae901 | ||
|
|
22b135a116 | ||
|
|
0f08983d85 | ||
|
|
e3e86343fc | ||
|
|
7b6dd880f7 | ||
|
|
b7f4020133 | ||
|
|
c46c7c7584 | ||
|
|
552af8b988 | ||
|
|
4f8ff361dc | ||
|
|
0010b47439 | ||
|
|
4b86b65d07 | ||
|
|
248489401a | ||
|
|
bc5992daf6 | ||
|
|
fdacfb0119 | ||
|
|
0d5d35d052 | ||
|
|
843c96b4b3 | ||
|
|
58dc02ebf2 | ||
|
|
c239f7de25 | ||
|
|
ac8540c3c5 | ||
|
|
22d904db95 | ||
|
|
741c2952d4 | ||
|
|
96f6979c4f | ||
|
|
c5379c1ab6 | ||
|
|
a4a5205fd7 | ||
|
|
c5ad4e7998 | ||
|
|
270dc2e199 | ||
|
|
948a0b6e81 | ||
|
|
87b8ecb13a | ||
|
|
e44ddcac63 | ||
|
|
00e9ad5217 | ||
|
|
96c3879bed | ||
|
|
57f460de2f | ||
|
|
6caacacf6d | ||
|
|
60ac5af682 | ||
|
|
caa94380ac | ||
|
|
0793380b40 | ||
|
|
1adadf585d | ||
|
|
e5ffdb9c77 | ||
|
|
6da5201092 | ||
|
|
b36ae19434 | ||
|
|
2307eac613 | ||
|
|
127ea40ae7 | ||
|
|
6aef600d48 | ||
|
|
98d76a0326 | ||
|
|
6ea6dcf05b | ||
|
|
627797800d | ||
|
|
c6cc03ed0c | ||
|
|
3d7b550f52 | ||
|
|
751d6f4ae6 | ||
|
|
a5c72ab51d | ||
|
|
9bbc88762b | ||
|
|
ceae00dddf | ||
|
|
3634c54e8d | ||
|
|
d74942a03d | ||
|
|
70c5e3e076 | ||
|
|
4cb1b32009 | ||
|
|
3268e90f5e | ||
|
|
e98170816a | ||
|
|
52b92f4db8 | ||
|
|
a2761754da | ||
|
|
805a11345c | ||
|
|
1ab62aec37 | ||
|
|
915363f976 | ||
|
|
205fafa577 | ||
|
|
be2daf4ad5 | ||
|
|
8ecfaa4adf | ||
|
|
03bfcf6462 | ||
|
|
39bec5ff32 | ||
|
|
246839d64a | ||
|
|
3862deb398 | ||
|
|
5954608577 | ||
|
|
984d2fded6 | ||
|
|
a4f04ed45a | ||
|
|
07736e8dcb | ||
|
|
00fc082d68 | ||
|
|
c72daea868 | ||
|
|
74c95c2542 | ||
|
|
7de060b08d | ||
|
|
572b41eb50 | ||
|
|
28866e9567 | ||
|
|
c52e189734 | ||
|
|
8ef5ada238 | ||
|
|
316e2730ac | ||
|
|
1f15b81d61 | ||
|
|
77e94da7bb | ||
|
|
03a97b6170 | ||
|
|
7622fc06ab | ||
|
|
73a08a248d | ||
|
|
9009d74652 | ||
|
|
1ad24ae15c | ||
|
|
3927da46aa | ||
|
|
1a6bca81f6 | ||
|
|
9e038946a1 | ||
|
|
824af85bdf | ||
|
|
5aabfc78bc | ||
|
|
f2621c7ff0 | ||
|
|
6b01084f8e | ||
|
|
1b7ecd111d | ||
|
|
832af0bafb | ||
|
|
4011c4e05e | ||
|
|
1697269ce7 | ||
|
|
208b65c5cf | ||
|
|
849a8357ba | ||
|
|
7cebd20fe7 |
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
||||
VERSION export-subst
|
||||
10
.gitignore
vendored
Normal file
10
.gitignore
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
src/*.o
|
||||
src/*.mo
|
||||
src/dnsmasq.pot
|
||||
src/dnsmasq
|
||||
src/dnsmasq_baseline
|
||||
src/.copts_*
|
||||
contrib/lease-tools/dhcp_lease_time
|
||||
contrib/lease-tools/dhcp_release
|
||||
contrib/lease-tools/dhcp_release6
|
||||
|
||||
6
.gitmodules
vendored
Normal file
6
.gitmodules
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
[submodule "debian"]
|
||||
path = debian
|
||||
url = git://thekelleys.org.uk/dnsmasq-debian.git
|
||||
[submodule "submodules/dnsmasq-debian"]
|
||||
path = submodules/dnsmasq-debian
|
||||
url = https://thekelleys.org.uk/git/dnsmasq-debian
|
||||
3
Android.mk
Normal file
3
Android.mk
Normal file
@@ -0,0 +1,3 @@
|
||||
ifneq ($(TARGET_SIMULATOR),true)
|
||||
include $(call all-subdir-makefiles)
|
||||
endif
|
||||
2509
CHANGELOG.archive
Normal file
2509
CHANGELOG.archive
Normal file
File diff suppressed because it is too large
Load Diff
43
COPYING
43
COPYING
@@ -1,12 +1,12 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
@@ -15,7 +15,7 @@ software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
@@ -55,8 +55,8 @@ patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
@@ -110,7 +110,7 @@ above, provided that you also meet all of these conditions:
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
@@ -168,7 +168,7 @@ access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
@@ -225,7 +225,7 @@ impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
@@ -255,7 +255,7 @@ make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
@@ -277,9 +277,9 @@ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
@@ -291,7 +291,7 @@ convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) 19yy <name of author>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -303,17 +303,16 @@ the "copyright" line and a pointer to where the full notice is found.
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) 19yy name of author
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
@@ -336,5 +335,5 @@ necessary. Here is a sample; alter the names:
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
||||
|
||||
674
COPYING-v3
Normal file
674
COPYING-v3
Normal file
@@ -0,0 +1,674 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||
@@ -1,94 +0,0 @@
|
||||
DBus support must be enabled at compile-time and run-time. Ensure
|
||||
that src/config.h contains the line
|
||||
|
||||
#define HAVE_DBUS.
|
||||
|
||||
and that /etc/dnsmasq.conf contains the line
|
||||
|
||||
enable-dbus
|
||||
|
||||
Because dnsmasq can operate stand-alone from the DBus, and may need to provide
|
||||
service before the dbus daemon is available, it will continue to run
|
||||
if the DBus connection is not available at startup. The DBus will be polled
|
||||
every 250ms until a connection is established. Start of polling and final
|
||||
connection establishment are both logged. When dnsmasq establishes a
|
||||
connection to the dbus, it sends the signal "Up". Anything controlling
|
||||
the server settings in dnsmasq should re-invoke the SetServers method
|
||||
(q.v.) when it sees this signal. This allows dnsmasq to be restarted
|
||||
and avoids startup races with the provider of nameserver information.
|
||||
|
||||
|
||||
Dnsmasq provides one service on the DBus: uk.org.thekelleys.dnsmasq
|
||||
and a single object: /uk/org/thekelleys/dnsmasq
|
||||
|
||||
Methods are of the form
|
||||
|
||||
uk.org.thekelleys.<method>
|
||||
|
||||
Available methods are:
|
||||
|
||||
GetVersion
|
||||
----------
|
||||
Returns a string containing the version of dnsmasq running.
|
||||
|
||||
ClearCache
|
||||
----------
|
||||
Returns nothing. Clears the domain name cache and re-reads
|
||||
/etc/hosts. The same as sending dnsmasq a HUP signal.
|
||||
|
||||
SetServers
|
||||
----------
|
||||
Returns nothing. Takes a set of arguments representing the new
|
||||
upstream DNS servers to be used by dnsmasq. IPv4 addresses are
|
||||
represented as a UINT32 (in network byte order) and IPv6 addresses
|
||||
are represented as sixteen BYTEs (since there is no UINT128 type).
|
||||
Each server address may be followed by one or more STRINGS, which are
|
||||
the domains for which the preceding server should be used.
|
||||
|
||||
Examples.
|
||||
|
||||
UINT32: <address1>
|
||||
UNIT32: <address2>
|
||||
|
||||
is equivalent to
|
||||
|
||||
--server=<address1> --server=<address2>
|
||||
|
||||
|
||||
UINT32 <address1>
|
||||
UINT32 <address2>
|
||||
STRING "somedomain.com"
|
||||
|
||||
is equivalent to
|
||||
|
||||
--server=<address1> --server=/somedomain.com/<address2>
|
||||
|
||||
UINT32 <address1>
|
||||
UINT32 <address2>
|
||||
STRING "somedomain.com"
|
||||
UINT32 <address3>
|
||||
STRING "anotherdomain.com"
|
||||
STRING "thirddomain.com"
|
||||
|
||||
is equivalent to
|
||||
|
||||
--server=<address1>
|
||||
--server=/somedomain.com/<address2>
|
||||
--server=/anotherdomain.com/thirddomain.com/<address3>
|
||||
|
||||
Am IPv4 address of 0.0.0.0 is interpreted as "no address, local only",
|
||||
so
|
||||
|
||||
UINT32: <0.0.0.0>
|
||||
STRING "local.domain"
|
||||
|
||||
is equivalent to
|
||||
|
||||
--local=/local.domain/
|
||||
|
||||
|
||||
Each call to SetServers completely replaces the set of servers
|
||||
specified by via the DBus, but it leaves any servers specified via the
|
||||
command line or /etc/dnsmasq.conf or /etc/resolv.conf alone.
|
||||
|
||||
|
||||
310
FAQ
310
FAQ
@@ -1,7 +1,7 @@
|
||||
Q: Why does dnsmasq open UDP ports >1024 as well as port 53.
|
||||
Is this a security problem/trojan/backdoor?
|
||||
|
||||
A: The high ports that dnsmasq opens is for replies from the upstream
|
||||
A: The high ports that dnsmasq opens are for replies from the upstream
|
||||
nameserver(s). Queries from dnsmasq to upstream nameservers are sent
|
||||
from these ports and replies received to them. The reason for doing this is
|
||||
that most firewall setups block incoming packets _to_ port 53, in order
|
||||
@@ -9,13 +9,21 @@ A: The high ports that dnsmasq opens is for replies from the upstream
|
||||
from port 53 the replies would be _to_ port 53 and get blocked.
|
||||
|
||||
This is not a security hole since dnsmasq will only accept replies to that
|
||||
port: queries are dropped. The replies must be to oustanding queries
|
||||
port: queries are dropped. The replies must be to outstanding queries
|
||||
which dnsmasq has forwarded, otherwise they are dropped too.
|
||||
|
||||
Addendum: dnsmasq now has the option "query-port" (-Q), which allows
|
||||
you to specify the UDP port to be used for this purpose. If not
|
||||
specified, the operating system will select an available port number
|
||||
just as it did before.
|
||||
|
||||
Second addendum: following the discovery of a security flaw in the
|
||||
DNS protocol, dnsmasq from version 2.43 has changed behavior. It
|
||||
now uses a new, randomly selected, port for each query. The old
|
||||
default behaviour (use one port allocated by the OS) is available by
|
||||
setting --query-port=0, and setting the query port to a positive
|
||||
value still works. You should think hard and know what you are
|
||||
doing before using either of these options.
|
||||
|
||||
Q: Why doesn't dnsmasq support DNS queries over TCP? Don't the RFC's specify
|
||||
that?
|
||||
@@ -39,18 +47,19 @@ A: They are negative entries: that's what the N flag means. Dnsmasq asked
|
||||
|
||||
Q: Will dnsmasq compile/run on non-Linux systems?
|
||||
|
||||
A: Yes, there is explicit support for *BSD and MacOS X. There are
|
||||
start-up scripts for MacOS X Tiger and Panther in /contrib. Earlier
|
||||
dnsmasq releases ran under Solaris, but that capability has
|
||||
probably rotted. Dnsmasq will link with uclibc to provide small
|
||||
A: Yes, there is explicit support for *BSD and MacOS X and Solaris.
|
||||
There are start-up scripts for MacOS X Tiger and Panther
|
||||
in /contrib. Dnsmasq will link with uclibc to provide small
|
||||
binaries suitable for use in embedded systems such as
|
||||
routers. (There's special code to support machines with flash
|
||||
filesystems and no battery-backed RTC.)
|
||||
If you encounter make errors with *BSD, try installing gmake from
|
||||
ports and building dnsmasq with "make MAKE=gmake"
|
||||
For other systems, try altering the settings in config.h.
|
||||
|
||||
Q: My companies' nameserver knows about some names which aren't in the
|
||||
Q: My company's nameserver knows about some names which aren't in the
|
||||
public DNS. Even though I put it first in /etc/resolv.conf, it
|
||||
dosen't work: dnsmasq seems not to use the nameservers in the order
|
||||
doesn't work: dnsmasq seems not to use the nameservers in the order
|
||||
given. What am I doing wrong?
|
||||
|
||||
A: By default, dnsmasq treats all the nameservers it knows about as
|
||||
@@ -103,7 +112,7 @@ A: Resolver code sometime does strange things when given names without
|
||||
hostname will fix things. (ie "ping myhost" fails, but "ping
|
||||
myhost." works. The solution is to make sure that all your hosts
|
||||
have a domain set ("domain" in resolv.conf, or set a domain in
|
||||
your DHCP server, see below fr Windows XP and Mac OS X).
|
||||
your DHCP server, see below for Windows XP and Mac OS X).
|
||||
Any domain will do, but "localnet" is traditional. Now when you
|
||||
resolve "myhost" the resolver will attempt to look up
|
||||
"myhost.localnet" so you need to have dnsmasq reply to that name.
|
||||
@@ -135,19 +144,19 @@ Q: Who are Verisign, what do they have to do with the bogus-nxdomain
|
||||
option in dnsmasq and why should I wory about it?
|
||||
|
||||
A: [note: this was written in September 2003, things may well change.]
|
||||
Versign run the .com and .net top-level-domains. They have just
|
||||
Verisign run the .com and .net top-level-domains. They have just
|
||||
changed the configuration of their servers so that unknown .com and
|
||||
.net domains, instead of returning an error code NXDOMAIN, (no such
|
||||
domain) return the address of a host at Versign which runs a web
|
||||
domain) return the address of a host at Verisign which runs a web
|
||||
server showing a search page. Most right-thinking people regard
|
||||
this new behaviour as broken :-). You can test to see if you are
|
||||
suffering Versign brokeness by run a command like
|
||||
suffering Verisign brokenness by run a command like
|
||||
|
||||
host jlsdajkdalld.com
|
||||
|
||||
If you get "jlsdajkdalld.com" does not exist, then all is fine, if
|
||||
host returns an IP address, then the DNS is broken. (Try a few
|
||||
different unlikely domains, just in case you picked a wierd one
|
||||
different unlikely domains, just in case you picked a weird one
|
||||
which really _is_ registered.)
|
||||
|
||||
Assuming that your DNS is broken, and you want to fix it, simply
|
||||
@@ -171,7 +180,7 @@ A: There are a couple of configuration gotchas which have been
|
||||
whilst the ISC one works.
|
||||
|
||||
The first thing to check is the broadcast address set for the
|
||||
ethernet interface. This is normally the adddress on the connected
|
||||
ethernet interface. This is normally the address on the connected
|
||||
network with all ones in the host part. For instance if the
|
||||
address of the ethernet interface is 192.168.55.7 and the netmask
|
||||
is 255.255.255.0 then the broadcast address should be
|
||||
@@ -196,7 +205,7 @@ A: By default, none of the DHCP clients send the host-name when asking
|
||||
send with the "hostname" keyword in /etc/network/interfaces. (See
|
||||
"man interfaces" for details.) That doesn't work for dhclient, were
|
||||
you have to add something like "send host-name daisy" to
|
||||
/etc/dhclient.conf [Update: the lastest dhcpcd packages _do_ send
|
||||
/etc/dhclient.conf [Update: the latest dhcpcd packages _do_ send
|
||||
the hostname by default.
|
||||
|
||||
Q: I'm network booting my machines, and trying to give them static
|
||||
@@ -225,55 +234,72 @@ A: What is happening is this: The boot process sends a DHCP
|
||||
Q: What network types are supported by the DHCP server?
|
||||
|
||||
A: Ethernet (and 802.11 wireless) are supported on all platforms. On
|
||||
Linux Token Ring is also supported.
|
||||
Linux all network types (including FireWire) are supported.
|
||||
|
||||
Q: What is this strange "bind-interface" option?
|
||||
Q: What are these strange "bind-interfaces" and "bind-dynamic" options?
|
||||
|
||||
A: The DNS spec says that the reply to a DNS query must come from the
|
||||
same address it was sent to. The traditional way to write an UDP
|
||||
server to do this is to find all of the addresses belonging to the
|
||||
machine (ie all the interfaces on the machine) and then create a
|
||||
socket for each interface which is bound to the address of the
|
||||
interface. Then when a packet is sent to address A, it is received
|
||||
on the socket bound to address A and when the reply is also sent
|
||||
via that socket, the source address is set to A by the kernel and
|
||||
everything works. This is the how dnsmasq works when
|
||||
"bind-interfaces" is set, with the obvious extension that is misses
|
||||
out creating sockets for some interfaces depending on the
|
||||
--interface, --address and --except-interface flags. The
|
||||
disadvantage of this approach is that it breaks if interfaces don't
|
||||
exist or are not configured when the daemon starts and does the
|
||||
socket creation step. In a hotplug-aware world this is a real
|
||||
problem.
|
||||
A: Dnsmasq from v2.63 can operate in one of three different "networking
|
||||
modes". This is unfortunate as it requires users configuring dnsmasq
|
||||
to take into account some rather bizarre constraints and select the
|
||||
mode which best fits the requirements of a particular installation.
|
||||
The origin of these are deficiencies in the Unix networking
|
||||
model and APIs and each mode has different advantages and
|
||||
problems. Just to add to the confusion, not all modes are available on
|
||||
all platforms (due the to lack of supporting network APIs).To further
|
||||
add to the confusion, the rules for the DHCP subsystem on dnsmasq are
|
||||
different to the rules for the DNS and TFTP subsystems.
|
||||
|
||||
The alternative approach is to have only one socket, which is bound
|
||||
to the correct port and the wildcard IP address (0.0.0.0). That
|
||||
socket will receive _all_ packets sent to port 53, no matter what
|
||||
destination address they have. This solves the problem of
|
||||
interfaces which are created or reconfigured after daemon
|
||||
start-up. To make this work is more complicated because of the
|
||||
"reply source address" problem. When a UDP packet is sent by a
|
||||
socket bound to 0.0.0.0 its source address will be set to the
|
||||
address of one of the machine's interfaces, but which one is not
|
||||
determined and can vary depending on the OS being run. To get round
|
||||
this it is neccessary to use a scary advanced API to determine the
|
||||
address to which a query was sent, and force that to be the source
|
||||
address in the reply. For IPv4 this stuff in non-portable and quite
|
||||
often not even available (It's different between FreeBSD 5.x and
|
||||
Linux, for instance, and FreeBSD 4.x, Linux 2.0.x and OpenBSD don't
|
||||
have it at all.) Hence "bind-interfaces" has to always be available
|
||||
as a fall back. For IPv6 the API is standard and universally
|
||||
available.
|
||||
The three modes are "wildcard", "bind-interfaces" and "bind-dynamic".
|
||||
|
||||
It could be argued that if the --interface or --address flags are
|
||||
used then binding interfaces is more appropriate, but using
|
||||
wildcard binding means that dnsmasq will quite happily start up
|
||||
after being told to use interfaces which don't exist, but which are
|
||||
created later. Wildcard binding breaks the scenario when dnsmasq is
|
||||
listening on one interface and another server (most probably BIND)
|
||||
is listening on another. It's not possible for BIND to bind to an
|
||||
(address,port) pair when dnsmasq has bound (wildcard,port), hence
|
||||
the ability to explicitly turn off wildcard binding.
|
||||
In "wildcard" mode, dnsmasq binds the wildcard IP address (0.0.0.0 or
|
||||
::). This allows it to receive all the packets sent to the server on
|
||||
the relevant port. Access control (--interface, --except-interface,
|
||||
--listen-address, etc) is implemented by dnsmasq: it queries the
|
||||
kernel to determine the interface on which a packet was received and
|
||||
the address to which it was sent, and applies the configured
|
||||
rules. Wildcard mode is the default if neither of the other modes are
|
||||
specified.
|
||||
|
||||
In "bind-interfaces" mode, dnsmasq runs through all the network
|
||||
interfaces available when it starts, finds the set of IP addresses on
|
||||
those interfaces, filters that set using the access control
|
||||
configuration, and then binds the set of IP addresses. Only packets
|
||||
sent to the allowed addresses are delivered by the kernel to dnsmasq.
|
||||
|
||||
In "bind-dynamic" mode, access control filtering is done both by
|
||||
binding individual IP addresses, as for bind-interfaces, and by
|
||||
inspecting individual packets on arrival as for wildcard mode. In
|
||||
addition, dnsmasq notices when new interfaces appear or new addresses
|
||||
appear on existing interfaces, and the resulting IP addresses are
|
||||
bound automatically without having to restart dnsmasq.
|
||||
|
||||
The mode chosen has four different effects: co-existence with other
|
||||
servers, semantics of --interface access control, effect of new
|
||||
interfaces, and legality of --interface specifications for
|
||||
non-existent interfaces. We will deal with these in order.
|
||||
|
||||
A dnsmasq instance running in wildcard mode precludes a machine from
|
||||
running a second instance of dnsmasq or any other DNS, TFTP or DHCP
|
||||
server. Attempts to do so will fail with an "address in use" error.
|
||||
Dnsmasq running in --bind-interfaces or bind-dynamic mode allow other
|
||||
instances of dnsmasq or other servers, as long as no two servers are
|
||||
configured to listen on the same interface address.
|
||||
|
||||
The semantics of --interface varies subtly between wildcard or
|
||||
bind-dynamic mode and bind-interfaces mode. The situation where this
|
||||
matters is a request which arrives via one interface (A), but with a
|
||||
destination address of a second interface (B) and when dnsmasq is
|
||||
configured to listen only on B. In wildcard or bind-dynamic mode, such
|
||||
a request will be ignored, in bind-interfaces mode, it will be
|
||||
accepted.
|
||||
|
||||
The creation of new network interfaces after dnsmasq starts is ignored
|
||||
by dnsmasq when in --bind-interfaces mode. In wildcard or bind-dynamic
|
||||
mode, such interfaces are handled normally.
|
||||
|
||||
An --interface specification for a non-existent interface is a fatal
|
||||
error at start-up when in --bind-interfaces mode, by just generates a
|
||||
warning in wildcard or bind-dynamic mode.
|
||||
|
||||
Q: Why doesn't Kerberos work/why can't I get sensible answers to
|
||||
queries for SRV records.
|
||||
@@ -287,15 +313,25 @@ Q: Can I get email notification when a new version of dnsmasq is
|
||||
released?
|
||||
|
||||
A: Yes, new releases of dnsmasq are always announced through
|
||||
freshmeat.net, and they allow you to subcribe to email alerts when
|
||||
freshmeat.net, and they allow you to subscribe to email alerts when
|
||||
new versions of particular projects are released. New releases are
|
||||
also announced in the dnsmasq-discuss mailing list, subscribe at
|
||||
http://lists.thekelleys.org.uk/mailman/listinfo/dnsmasq-discuss
|
||||
|
||||
Q: What does the dhcp-authoritative option do?
|
||||
|
||||
A: See http://www.isc.org/index.pl?/sw/dhcp/authoritative.php - that's
|
||||
for the ISC daemon, but the same applies to dnsmasq.
|
||||
A: The DHCP spec says that when a DHCP server receives a renewal request
|
||||
from a client it has no knowledge of, it should just ignore it.
|
||||
This is because it's supported to have more than one DHCP server
|
||||
on a network, and another DHCP server may be dealing with the client.
|
||||
This has the unfortunate effect that when _no_ DHCP replies to
|
||||
the client, it takes some time for the client to time-out and start
|
||||
to get a new lease. Setting this option makes dnsmasq violate the
|
||||
standard to the extent that it will send a NAK reply to the client,
|
||||
causing it to immediately start to get a new lease. This improves
|
||||
behaviour when machines move networks, and in the case that the DHCP
|
||||
lease database is lost. As long as there are not more tha one DHCP
|
||||
server on the network, it's safe to enable the option.
|
||||
|
||||
Q: Why does my Gentoo box pause for a minute before getting a new
|
||||
lease?
|
||||
@@ -309,7 +345,7 @@ A: Because when a Gentoo box shuts down, it releases its lease with
|
||||
|
||||
Q: My laptop has two network interfaces, a wired one and a wireless
|
||||
one. I never use both interfaces at the same time, and I'd like the
|
||||
same IP and configuration to be used irrespcetive of which
|
||||
same IP and configuration to be used irrespective of which
|
||||
interface is in use. How can I do that?
|
||||
|
||||
A: By default, the identity of a machine is determined by using the
|
||||
@@ -324,6 +360,63 @@ A: By default, the identity of a machine is determined by using the
|
||||
dhcpcd uses the "-I" flag. Windows uses a registry setting,
|
||||
see http://www.jsiinc.com/SUBF/TIP2800/rh2845.htm
|
||||
|
||||
Addendum:
|
||||
From version 2.46, dnsmasq has a solution to this which doesn't
|
||||
involve setting client-IDs. It's possible to put more than one MAC
|
||||
address in a --dhcp-host configuration. This tells dnsmasq that it
|
||||
should use the specified IP for any of the specified MAC addresses,
|
||||
and furthermore it gives dnsmasq permission to summarily abandon a
|
||||
lease to one of the MAC addresses if another one comes along. Note
|
||||
that this will work fine only as longer as only one interface is
|
||||
up at any time. There is no way for dnsmasq to enforce this
|
||||
constraint: if you configure multiple MAC addresses and violate
|
||||
this rule, bad things will happen.
|
||||
|
||||
Addendum-II: The link above is dead, the former contents of the link are:
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
How can I keep the same DHCP client reservation, if the MAC address changes?
|
||||
|
||||
When you reserve an IP address for a DHCP client, you provide the
|
||||
MAC address of the client's NIC.
|
||||
|
||||
It is possible to use a custom identifier, which is sent as
|
||||
option 61 in the client's DHCP Discover and Request packet.
|
||||
|
||||
The DhcpClientIdentifier is a REG_DWORD value that is located at:
|
||||
|
||||
Windows NT 4.0 SP2+
|
||||
|
||||
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\<Adapter Name>'X'\Parameters\Tcpip
|
||||
|
||||
where <Adapter Name> is the NIC driver name and 'X' is the number of the NIC.
|
||||
|
||||
Windows 2000
|
||||
|
||||
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\TcpIp\Parameters\Interfaces\<NIC GUID>
|
||||
|
||||
where <NIC GUID> is the GUID of the NIC.
|
||||
|
||||
The valid range of data is 0x0 - 0xFFFFFFFF. The custom identifier is send as 4 bytes,
|
||||
8 hexadecimal character, in groups of 2 hexadecimal characters, with the groups being
|
||||
sent in reverse order. If the custom identifier is less than 8 hexadeciaml characters,
|
||||
it is zero padded at the end. Examples:
|
||||
|
||||
Custom Client Client Reservation
|
||||
Identifier on DHCP Server
|
||||
12345678 78563412
|
||||
123456 56341200
|
||||
1234 34120000
|
||||
1234567 67452301
|
||||
12345 45230100
|
||||
123 23010000
|
||||
A18F42 428FA100
|
||||
CF432 32F40C00
|
||||
C32D1BE BED1320C
|
||||
|
||||
-------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
Q: Can dnsmasq do DHCP on IP-alias interfaces?
|
||||
|
||||
A: Yes, from version-2.21. The support is only available running under
|
||||
@@ -334,7 +427,7 @@ A: Yes, from version-2.21. The support is only available running under
|
||||
If a physical interface has more than one IP address or aliases
|
||||
with extra IP addresses, then any dhcp-ranges corresponding to
|
||||
these addresses can be used for address allocation. So if an
|
||||
interface has addresses 192.168.1.0/24 and 192.68.2.0/24 and there
|
||||
interface has addresses 192.168.1.0/24 and 192.168.2.0/24 and there
|
||||
are DHCP ranges 192.168.1.100-192.168.1.200 and
|
||||
192.168.2.100-192.168.2.200 then both ranges would be used for host
|
||||
connected to the physical interface. A more typical use might be to
|
||||
@@ -361,7 +454,7 @@ A: Probably the nameserver is an authoritative nameserver for a
|
||||
Q: Does the dnsmasq DHCP server probe addresses before allocating
|
||||
them, as recommended in RFC2131?
|
||||
|
||||
A: Yes, dynmaically allocated IP addresses are checked by sending an
|
||||
A: Yes, dynamically allocated IP addresses are checked by sending an
|
||||
ICMP echo request (ping). If a reply is received, then dnsmasq
|
||||
assumes that the address is in use, and attempts to allocate an
|
||||
different address. The wait for a reply is between two and three
|
||||
@@ -378,11 +471,90 @@ A: This a variant on the iptables problem. Explicit details on how to
|
||||
http://lists.thekelleys.org.uk/pipermail/dnsmasq-discuss/2005q3/000431.html
|
||||
|
||||
|
||||
Q: Dnsmasq logs "running as root because setting capabilities failed"
|
||||
when it starts up. Why did that happen and what can do to fix it?
|
||||
Q: I'm using dnsmasq on a machine with the shorewall firewall, and
|
||||
DHCP doesn't work. What's the problem?
|
||||
|
||||
A: This a variant on the iptables problem. Explicit details on how to
|
||||
proceed can be found at
|
||||
http://lists.thekelleys.org.uk/pipermail/dnsmasq-discuss/2007q4/001764.html
|
||||
|
||||
|
||||
Q: Dnsmasq fails to start up with a message about capabilities.
|
||||
Why did that happen and what can do to fix it?
|
||||
|
||||
A: Change your kernel configuration: either deselect CONFIG_SECURITY
|
||||
_or_ select CONFIG_SECURITY_CAPABILITIES.
|
||||
_or_ select CONFIG_SECURITY_CAPABILITIES. Alternatively, you can
|
||||
remove the need to set capabilities by running dnsmasq as root.
|
||||
|
||||
|
||||
Q: Where can I get .rpms Suitable for openSUSE/SLES?
|
||||
|
||||
A: Dnsmasq is in openSUSE itself, and the latest releases are also
|
||||
available at http://download.opensuse.org/repositories/network/
|
||||
|
||||
|
||||
Q: Can I run dnsmasq in a Linux vserver?
|
||||
|
||||
A: Yes, as a DNS server, dnsmasq will just work in a vserver.
|
||||
To use dnsmasq's DHCP function you need to give the vserver
|
||||
extra system capabilities. Please note that doing so will lesser
|
||||
the overall security of your system. The capabilities
|
||||
required are NET_ADMIN and NET_RAW. NET_ADMIN is essential, NET_RAW
|
||||
is required to do an ICMP "ping" check on newly allocated
|
||||
addresses. If you don't need this check, you can disable it with
|
||||
--no-ping and omit the NET_RAW capability.
|
||||
Adding the capabilities is done by adding them, one per line, to
|
||||
either /etc/vservers/<vservername>/ccapabilities for a 2.4 kernel or
|
||||
/etc/vservers/<vservername>/bcapabilities for a 2.6 kernel (please
|
||||
refer to the vserver documentation for more information).
|
||||
|
||||
|
||||
Q: What's the problem with syslog and dnsmasq?
|
||||
|
||||
A: In almost all cases: none. If you have the normal arrangement with
|
||||
local daemons logging to a local syslog, which then writes to disk,
|
||||
then there's never a problem. If you use network logging, then
|
||||
there's a potential problem with deadlock: the syslog daemon will
|
||||
do DNS lookups so that it can log the source of log messages,
|
||||
these lookups will (depending on exact configuration) go through
|
||||
dnsmasq, which also sends log messages. With bad timing, you can
|
||||
arrive at a situation where syslog is waiting for dnsmasq, and
|
||||
dnsmasq is waiting for syslog; they will both wait forever. This
|
||||
problem is fixed from dnsmasq-2.39, which introduces asynchronous
|
||||
logging: dnsmasq no longer waits for syslog and the deadlock is
|
||||
broken. There is a remaining problem in 2.39, where "log-queries"
|
||||
is in use. In this case most DNS queries generate two log lines, if
|
||||
these go to a syslog which is doing a DNS lookup for each log line,
|
||||
then those queries will in turn generate two more log lines, and a
|
||||
chain reaction runaway will occur. To avoid this, use syslog-ng
|
||||
and turn on syslog-ng's dns-cache function.
|
||||
|
||||
|
||||
Q: DHCP doesn't work with windows Vista, but everything else is fine.
|
||||
|
||||
A: The DHCP client on windows Vista (and possibly later versions)
|
||||
demands that the DHCP server send replies as broadcasts. Most other
|
||||
clients don't do this. The broadcasts are send to
|
||||
255.255.255.255. A badly configured firewall which blocks such
|
||||
packets will show exactly these symptoms (Vista fails, others
|
||||
work).
|
||||
|
||||
|
||||
Q: DHCP doesn't work with windows 7 but everything else is fine.
|
||||
|
||||
A: There seems to be a problem if Windows 7 doesn't get a value for
|
||||
DHCP option 252 in DHCP packets it gets from the server. The
|
||||
symptoms have been variously reported as continual DHCPINFORM
|
||||
requests in an attempt to get an option-252, or even ignoring DHCP
|
||||
offers completely (and failing to get an IP address) if there is no
|
||||
option-252 supplied. DHCP option 252 is for WPAD, WWW Proxy
|
||||
Auto Detection and if you don't want or need to use that, then
|
||||
simplest fix seems to be to supply an empty option with:
|
||||
|
||||
dhcp-option=252,"\n"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
190
Makefile
190
Makefile
@@ -1,42 +1,178 @@
|
||||
PREFIX?=/usr/local
|
||||
BINDIR = ${PREFIX}/sbin
|
||||
MANDIR = ${PREFIX}/share/man
|
||||
LOCALEDIR = ${PREFIX}/share/locale
|
||||
# dnsmasq is Copyright (c) 2000-2025 Simon Kelley
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; version 2 dated June, 1991, or
|
||||
# (at your option) version 3 dated 29 June, 2007.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# NOTE: Building the i18n targets requires GNU-make
|
||||
|
||||
|
||||
# Variables you may well want to override.
|
||||
|
||||
PREFIX = /usr/local
|
||||
BINDIR = $(PREFIX)/sbin
|
||||
MANDIR = $(PREFIX)/share/man
|
||||
LOCALEDIR = $(PREFIX)/share/locale
|
||||
BUILDDIR = $(SRC)
|
||||
DESTDIR =
|
||||
CFLAGS = -Wall -W -O2
|
||||
LDFLAGS =
|
||||
COPTS =
|
||||
RPM_OPT_FLAGS =
|
||||
LIBS =
|
||||
LUA = lua
|
||||
|
||||
#################################################################
|
||||
|
||||
# Variables you might want to override.
|
||||
|
||||
PKG_CONFIG = pkg-config
|
||||
INSTALL = install
|
||||
MSGMERGE = msgmerge
|
||||
MSGFMT = msgfmt
|
||||
XGETTEXT = xgettext
|
||||
|
||||
SRC = src
|
||||
PO = po
|
||||
PO = po
|
||||
MAN = man
|
||||
|
||||
CFLAGS?= -O2
|
||||
#################################################################
|
||||
|
||||
all :
|
||||
$(MAKE) I18N=-DNO_GETTEXT -f ../bld/Makefile -C $(SRC) dnsmasq
|
||||
# pmake way. (NB no spaces to keep gmake 3.82 happy)
|
||||
top!=pwd
|
||||
# GNU make way.
|
||||
top?=$(CURDIR)
|
||||
|
||||
clean :
|
||||
rm -f *~ $(SRC)/*.mo contrib/*/*~ */*~ $(SRC)/*.pot
|
||||
rm -f $(SRC)/*.o $(SRC)/dnsmasq core */core
|
||||
dbus_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_DBUS $(PKG_CONFIG) --cflags dbus-1`
|
||||
dbus_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_DBUS $(PKG_CONFIG) --libs dbus-1`
|
||||
ubus_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_UBUS "" --copy '-lubox -lubus'`
|
||||
idn_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_IDN $(PKG_CONFIG) --cflags libidn`
|
||||
idn_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_IDN $(PKG_CONFIG) --libs libidn`
|
||||
idn2_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_LIBIDN2 $(PKG_CONFIG) --cflags libidn2`
|
||||
idn2_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_LIBIDN2 $(PKG_CONFIG) --libs libidn2`
|
||||
ct_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_CONNTRACK $(PKG_CONFIG) --cflags libnetfilter_conntrack`
|
||||
ct_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_CONNTRACK $(PKG_CONFIG) --libs libnetfilter_conntrack`
|
||||
lua_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_LUASCRIPT $(PKG_CONFIG) --cflags $(LUA)`
|
||||
lua_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_LUASCRIPT $(PKG_CONFIG) --libs $(LUA)`
|
||||
nettle_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_DNSSEC $(PKG_CONFIG) --cflags 'nettle hogweed'`
|
||||
nettle_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_DNSSEC $(PKG_CONFIG) --libs 'nettle hogweed'`
|
||||
gmp_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_DNSSEC NO_GMP --copy -lgmp`
|
||||
sunos_libs = `if uname | grep SunOS >/dev/null 2>&1; then echo -lsocket -lnsl -lposix4; fi`
|
||||
nft_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_NFTSET $(PKG_CONFIG) --cflags libnftables`
|
||||
nft_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_NFTSET $(PKG_CONFIG) --libs libnftables`
|
||||
version = -DVERSION='\"`$(top)/bld/get-version $(top)`\"'
|
||||
|
||||
install : all install-common
|
||||
sum?=$(shell echo $(CC) -DDNSMASQ_COMPILE_FLAGS="$(CFLAGS)" -DDNSMASQ_COMPILE_OPTS $(COPTS) -E $(top)/$(SRC)/dnsmasq.h | ( md5sum 2>/dev/null || md5 ) | cut -f 1 -d ' ')
|
||||
sum!=echo $(CC) -DDNSMASQ_COMPILE_FLAGS="$(CFLAGS)" -DDNSMASQ_COMPILE_OPTS $(COPTS) -E $(top)/$(SRC)/dnsmasq.h | ( md5sum 2>/dev/null || md5 ) | cut -f 1 -d ' '
|
||||
copts_conf = .copts_$(sum)
|
||||
|
||||
install-common :
|
||||
install -d $(DESTDIR)$(BINDIR) -d $(DESTDIR)$(MANDIR)/man8
|
||||
install -m 644 $(MAN)/dnsmasq.8 $(DESTDIR)$(MANDIR)/man8
|
||||
install -m 755 $(SRC)/dnsmasq $(DESTDIR)$(BINDIR)
|
||||
objs = cache.o rfc1035.o util.o option.o forward.o network.o \
|
||||
dnsmasq.o dhcp.o lease.o rfc2131.o netlink.o dbus.o bpf.o \
|
||||
helper.o tftp.o log.o conntrack.o dhcp6.o rfc3315.o \
|
||||
dhcp-common.o outpacket.o radv.o slaac.o auth.o ipset.o pattern.o \
|
||||
domain.o dnssec.o blockdata.o tables.o loop.o inotify.o \
|
||||
poll.o rrfilter.o edns0.o arp.o crypto.o dump.o ubus.o \
|
||||
metrics.o domain-match.o nftset.o
|
||||
|
||||
all-i18n :
|
||||
$(MAKE) I18N=-DLOCALEDIR='\"$(LOCALEDIR)\"' -f ../bld/Makefile -C $(SRC) dnsmasq
|
||||
cd $(PO); for f in *.po; do \
|
||||
$(MAKE) -f ../bld/Makefile -C ../$(SRC) $${f/.po/.mo}; \
|
||||
hdrs = dnsmasq.h config.h dhcp-protocol.h dhcp6-protocol.h \
|
||||
dns-protocol.h radv-protocol.h ip6addr.h metrics.h
|
||||
|
||||
all : $(BUILDDIR)
|
||||
@cd $(BUILDDIR) && $(MAKE) \
|
||||
top="$(top)" \
|
||||
build_cflags="$(version) $(dbus_cflags) $(idn2_cflags) $(idn_cflags) $(ct_cflags) $(lua_cflags) $(nettle_cflags) $(nft_cflags)" \
|
||||
build_libs="$(dbus_libs) $(idn2_libs) $(idn_libs) $(ct_libs) $(lua_libs) $(sunos_libs) $(nettle_libs) $(gmp_libs) $(ubus_libs) $(nft_libs)" \
|
||||
-f $(top)/Makefile dnsmasq
|
||||
|
||||
mostly_clean :
|
||||
rm -f $(BUILDDIR)/*.mo $(BUILDDIR)/*.pot
|
||||
rm -f $(BUILDDIR)/.copts_* $(BUILDDIR)/*.o $(BUILDDIR)/dnsmasq.a $(BUILDDIR)/dnsmasq
|
||||
|
||||
clean : mostly_clean
|
||||
rm -f $(BUILDDIR)/dnsmasq_baseline
|
||||
rm -f core */core
|
||||
rm -f *~ contrib/*/*~ */*~
|
||||
|
||||
install : all
|
||||
$(INSTALL) -d $(DESTDIR)$(BINDIR)
|
||||
$(INSTALL) -d $(DESTDIR)$(MANDIR)/man8
|
||||
$(INSTALL) -m 644 $(MAN)/dnsmasq.8 $(DESTDIR)$(MANDIR)/man8
|
||||
$(INSTALL) -m 755 $(BUILDDIR)/dnsmasq $(DESTDIR)$(BINDIR)
|
||||
|
||||
all-i18n : $(BUILDDIR)
|
||||
@cd $(BUILDDIR) && $(MAKE) \
|
||||
top="$(top)" \
|
||||
i18n=-DLOCALEDIR=\'\"$(LOCALEDIR)\"\' \
|
||||
build_cflags="$(version) $(dbus_cflags) $(idn2_cflags) $(idn_cflags) $(ct_cflags) $(lua_cflags) $(nettle_cflags) $(nft_cflags)" \
|
||||
build_libs="$(dbus_libs) $(idn2_libs) $(idn_libs) $(ct_libs) $(lua_libs) $(sunos_libs) $(nettle_libs) $(gmp_libs) $(ubus_libs) $(nft_libs)" \
|
||||
-f $(top)/Makefile dnsmasq
|
||||
for f in `cd $(PO); echo *.po`; do \
|
||||
cd $(top) && cd $(BUILDDIR) && $(MAKE) top="$(top)" -f $(top)/Makefile $${f%.po}.mo; \
|
||||
done
|
||||
|
||||
install-i18n : all-i18n install-common
|
||||
cd $(SRC); ../bld/install-mo $(DESTDIR)$(LOCALEDIR)
|
||||
cd $(MAN); ../bld/install-man $(DESTDIR)$(MANDIR)
|
||||
install-i18n : all-i18n
|
||||
$(INSTALL) -d $(DESTDIR)$(BINDIR)
|
||||
$(INSTALL) -d $(DESTDIR)$(MANDIR)/man8
|
||||
$(INSTALL) -m 644 $(MAN)/dnsmasq.8 $(DESTDIR)$(MANDIR)/man8
|
||||
$(INSTALL) -m 755 $(BUILDDIR)/dnsmasq $(DESTDIR)$(BINDIR)
|
||||
cd $(BUILDDIR); $(top)/bld/install-mo $(DESTDIR)$(LOCALEDIR) $(INSTALL)
|
||||
cd $(MAN); ../bld/install-man $(DESTDIR)$(MANDIR) $(INSTALL)
|
||||
|
||||
merge :
|
||||
$(MAKE) I18N=-DLOCALEDIR='\"$(LOCALEDIR)\"' -f ../bld/Makefile -C $(SRC) dnsmasq.pot
|
||||
cd $(PO); for f in *.po; do \
|
||||
msgmerge -U $$f ../$(SRC)/dnsmasq.pot; \
|
||||
merge :
|
||||
@cd $(BUILDDIR) && $(MAKE) top="$(top)" -f $(top)/Makefile dnsmasq.pot
|
||||
for f in `cd $(PO); echo *.po`; do \
|
||||
echo -n msgmerge $(PO)/$$f && $(MSGMERGE) --no-wrap -U $(PO)/$$f $(BUILDDIR)/dnsmasq.pot; \
|
||||
done
|
||||
|
||||
# Canonicalise .po file.
|
||||
%.po :
|
||||
@cd $(BUILDDIR) && $(MAKE) -f $(top)/Makefile dnsmasq.pot
|
||||
mv $(PO)/$*.po $(PO)/$*.po.orig && $(MSGMERGE) --no-wrap $(PO)/$*.po.orig $(BUILDDIR)/dnsmasq.pot >$(PO)/$*.po;
|
||||
|
||||
$(BUILDDIR):
|
||||
mkdir -p $(BUILDDIR)
|
||||
|
||||
# rules below are helpers for size tracking
|
||||
|
||||
baseline : mostly_clean all
|
||||
@cd $(BUILDDIR) && \
|
||||
mv dnsmasq dnsmasq_baseline
|
||||
|
||||
bloatcheck : $(BUILDDIR)/dnsmasq_baseline mostly_clean all
|
||||
@cd $(BUILDDIR) && \
|
||||
$(top)/bld/bloat-o-meter dnsmasq_baseline dnsmasq; \
|
||||
size dnsmasq_baseline dnsmasq
|
||||
|
||||
# rules below are targets in recursive makes with cwd=$(BUILDDIR)
|
||||
|
||||
$(copts_conf): $(hdrs)
|
||||
@rm -f *.o .copts_*
|
||||
@touch $@
|
||||
|
||||
$(objs:.o=.c) $(hdrs):
|
||||
ln -s $(top)/$(SRC)/$@ .
|
||||
|
||||
$(objs): $(copts_conf) $(hdrs)
|
||||
|
||||
.c.o:
|
||||
$(CC) $(CFLAGS) $(COPTS) $(i18n) $(build_cflags) $(RPM_OPT_FLAGS) -c $<
|
||||
|
||||
dnsmasq : $(objs)
|
||||
$(CC) $(LDFLAGS) -o $@ $(objs) $(build_libs) $(LIBS)
|
||||
|
||||
dnsmasq.pot : $(objs:.o=.c) $(hdrs)
|
||||
$(XGETTEXT) -d dnsmasq --foreign-user --omit-header --keyword=_ -o $@ -i $(objs:.o=.c)
|
||||
|
||||
%.mo : $(top)/$(PO)/%.po dnsmasq.pot
|
||||
$(MSGMERGE) -o - $(top)/$(PO)/$*.po dnsmasq.pot | $(MSGFMT) -o $*.mo -
|
||||
|
||||
.PHONY : all clean mostly_clean install install-common all-i18n install-i18n merge baseline bloatcheck
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
|
||||
|
||||
Upgrading to dnsmasq V2
|
||||
-----------------------
|
||||
|
||||
Version 1.x of dnsmasq includes a facility for reading the dhcp.leases
|
||||
file written by ISC dhcpd. This allows the names of machines which
|
||||
have addresses allocated by DHCP to be included in the DNS.
|
||||
|
||||
Version 2.x of dnsmasq replaces the ISC dhcpd integration with a DHCP
|
||||
server integrated into dnsmasq. Versions 2.0-2.5 removed the ISC
|
||||
integration completely, but in version 2.6 it was re-enabled for
|
||||
backwards compatibility purposes. The change to an integrated DHCP
|
||||
server has the following advantages:
|
||||
|
||||
* Small. ISC dhcpd is a large and comprehensive DHCP solution. The
|
||||
dnsmasq DHCP server adds about 15k to DNS-only dnsmasq and provides
|
||||
all the facilities likely to be needed in the sort of networks
|
||||
which are targeted by dnsmasq.
|
||||
|
||||
* Easy to configure. All configuration is in one file and there are
|
||||
sensible defaults for common settings. Many applications will need
|
||||
just one extra line in /etc/dnsmasq.conf which tells it the range of
|
||||
addresses to allocate to DHCP.
|
||||
|
||||
* Support for static leases. When static leases are used with ISC DHCP
|
||||
they don't appear in the dhcp.leases file (since that file is used
|
||||
for storage of dynamic leases which aren't pre-configured.) Hence
|
||||
static leases cannot be used with dnsmasq unless each machine with a
|
||||
static lease is also inserted into /etc/hosts. This is not required
|
||||
with the dnsmasq DHCP server.
|
||||
|
||||
|
||||
DHCP configuration
|
||||
------------------
|
||||
|
||||
To convert an installation which is currently using ISC dhcpd, remove
|
||||
the ISC DHCP daemon. Unless you want dnsmasq to use the same file
|
||||
to store its leases it is necessary to remove the configuration line in
|
||||
/etc/dnsmasq.conf which specifies the dhcp.leases file.
|
||||
|
||||
To enable DHCP, simply add a line like this to /etc/dnsmasq.conf
|
||||
|
||||
dhcp-range=192.168.0.100,192.168.0.200,12h
|
||||
|
||||
which tells dnsmasq to us the addresses 192.168.0.100 to 192.168.0.200
|
||||
for dynamic IP addresses, and to issue twelve hour leases.
|
||||
|
||||
Each host will have its default route and DNS server set to be the
|
||||
address of the host running dnsmasq, and its netmask and broadcast
|
||||
address set correctly, so nothing else at all is required for a
|
||||
minimal system. Hosts which include a hostname in their DHCP request
|
||||
will have that name and their allocated address inserted into the DNS,
|
||||
in the same way as before.
|
||||
|
||||
Having started dnsmasq, tell any hosts on the network to renew their
|
||||
DHCP lease, so that dnsmasq's DHCP server becomes aware of them. For
|
||||
Linux, this is best done by killing-and-restarting the DHCP client
|
||||
daemon or taking the network interface down and then back up. For
|
||||
Windows 9x/Me, use the graphical tool "winipcfg". For Windows
|
||||
NT/2000/XP, use the command-line "ipconfig /renew"
|
||||
|
||||
For more complex DHCP configuration, refer to the doc/setup.html, the
|
||||
dnsmasq manpage and the annotated example configuration file. Also
|
||||
note that for some ISC dhcpd to dnsmasq DHCP upgrades there may be
|
||||
firewall issues: see the FAQ for details of this.
|
||||
|
||||
|
||||
26
bld/Android.mk
Normal file
26
bld/Android.mk
Normal file
@@ -0,0 +1,26 @@
|
||||
LOCAL_PATH := external/dnsmasq/src
|
||||
|
||||
#########################
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_SRC_FILES := bpf.c cache.c dbus.c dhcp.c dnsmasq.c \
|
||||
forward.c helper.c lease.c log.c \
|
||||
netlink.c network.c option.c rfc1035.c \
|
||||
rfc2131.c tftp.c util.c conntrack.c \
|
||||
dhcp6.c rfc3315.c dhcp-common.c outpacket.c \
|
||||
radv.c slaac.c auth.c ipset.c domain.c \
|
||||
dnssec.c dnssec-openssl.c blockdata.c tables.c \
|
||||
loop.c inotify.c poll.c rrfilter.c edns0.c arp.c \
|
||||
crypto.c dump.c ubus.c metrics.c \
|
||||
domain-match.c nftset.c
|
||||
|
||||
LOCAL_MODULE := dnsmasq
|
||||
|
||||
LOCAL_C_INCLUDES := external/dnsmasq/src
|
||||
|
||||
LOCAL_CFLAGS := -O2 -g -W -Wall -D__ANDROID__ -DNO_TFTP -DNO_SCRIPT
|
||||
LOCAL_SYSTEM_SHARED_LIBRARIES := libc libcutils
|
||||
|
||||
LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog
|
||||
|
||||
include $(BUILD_EXECUTABLE)
|
||||
18
bld/Makefile
18
bld/Makefile
@@ -1,18 +0,0 @@
|
||||
CFLAGS ?= -O2
|
||||
PKG_CONFIG ?= pkg-config
|
||||
|
||||
|
||||
OBJS = cache.o rfc1035.o util.o option.o forward.o isc.o network.o \
|
||||
dnsmasq.o dhcp.o lease.o rfc2131.o netlink.o dbus.o bpf.o
|
||||
|
||||
.c.o:
|
||||
$(CC) $(CFLAGS) $(I18N) `../bld/pkg-wrapper $(PKG_CONFIG) --cflags dbus-1` $(RPM_OPT_FLAGS) -Wall -W -c $<
|
||||
|
||||
dnsmasq : $(OBJS)
|
||||
$(CC) -o $@ $(OBJS) `../bld/pkg-wrapper $(PKG_CONFIG) --libs dbus-1` $(LIBS)
|
||||
|
||||
dnsmasq.pot : $(OBJS:.o=.c) dnsmasq.h config.h
|
||||
xgettext -d dnsmasq --foreign-user --keyword=_ -o dnsmasq.pot -i $(OBJS:.o=.c)
|
||||
|
||||
%.mo : ../po/%.po dnsmasq.pot
|
||||
msgmerge -o - ../po/$*.po dnsmasq.pot | msgfmt -o $*.mo -
|
||||
130
bld/bloat-o-meter
Executable file
130
bld/bloat-o-meter
Executable file
@@ -0,0 +1,130 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2004 Matt Mackall <mpm@selenic.com>
|
||||
#
|
||||
# Inspired by perl Bloat-O-Meter (c) 1997 by Andi Kleen
|
||||
#
|
||||
# This software may be used and distributed according to the terms
|
||||
# of the GNU General Public License, incorporated herein by reference.
|
||||
|
||||
import sys, os#, re
|
||||
|
||||
def usage():
|
||||
sys.stderr.write("usage: %s [-t] file1 file2\n" % sys.argv[0])
|
||||
sys.exit(-1)
|
||||
|
||||
f1, f2 = (None, None)
|
||||
flag_timing, dashes = (False, False)
|
||||
|
||||
for f in sys.argv[1:]:
|
||||
if f.startswith("-"):
|
||||
if f == "--": # sym_args
|
||||
dashes = True
|
||||
break
|
||||
if f == "-t": # timings
|
||||
flag_timing = True
|
||||
else:
|
||||
if not os.path.exists(f):
|
||||
sys.stderr.write("Error: file '%s' does not exist\n" % f)
|
||||
usage()
|
||||
if f1 is None:
|
||||
f1 = f
|
||||
elif f2 is None:
|
||||
f2 = f
|
||||
if flag_timing:
|
||||
import time
|
||||
if f1 is None or f2 is None:
|
||||
usage()
|
||||
|
||||
sym_args = " ".join(sys.argv[3 + flag_timing + dashes:])
|
||||
def getsizes(file):
|
||||
sym, alias, lut = {}, {}, {}
|
||||
for l in os.popen("readelf -W -s %s %s" % (sym_args, file)).readlines():
|
||||
l = l.strip()
|
||||
if not (len(l) and l[0].isdigit() and len(l.split()) == 8):
|
||||
continue
|
||||
num, value, size, typ, bind, vis, ndx, name = l.split()
|
||||
if ndx == "UND": continue # skip undefined
|
||||
if typ in ["SECTION", "FILES"]: continue # skip sections and files
|
||||
if "." in name: name = "static." + name.split(".")[0]
|
||||
value = int(value, 16)
|
||||
size = int(size, 16) if size.startswith('0x') else int(size)
|
||||
if vis != "DEFAULT" and bind != "GLOBAL": # see if it is an alias
|
||||
alias[(value, size)] = {"name" : name}
|
||||
else:
|
||||
sym[name] = {"addr" : value, "size": size}
|
||||
lut[(value, size)] = 0
|
||||
for addr, sz in iter(alias.keys()):
|
||||
# If the non-GLOBAL sym has an implementation elsewhere then
|
||||
# it's an alias, disregard it.
|
||||
if not (addr, sz) in lut:
|
||||
# If this non-GLOBAL sym does not have an implementation at
|
||||
# another address, then treat it as a normal symbol.
|
||||
sym[alias[(addr, sz)]["name"]] = {"addr" : addr, "size": sz}
|
||||
for l in os.popen("readelf -W -S " + file).readlines():
|
||||
x = l.split()
|
||||
if len(x)<6: continue
|
||||
# Should take these into account too!
|
||||
#if x[1] not in [".text", ".rodata", ".symtab", ".strtab"]: continue
|
||||
if x[1] not in [".rodata"]: continue
|
||||
sym[x[1]] = {"addr" : int(x[3], 16), "size" : int(x[5], 16)}
|
||||
return sym
|
||||
|
||||
if flag_timing:
|
||||
start_t1 = int(time.time() * 1e9)
|
||||
old = getsizes(f1)
|
||||
if flag_timing:
|
||||
end_t1 = int(time.time() * 1e9)
|
||||
start_t2 = int(time.time() * 1e9)
|
||||
new = getsizes(f2)
|
||||
if flag_timing:
|
||||
end_t2 = int(time.time() * 1e9)
|
||||
start_t3 = int(time.time() * 1e9)
|
||||
grow, shrink, add, remove, up, down = 0, 0, 0, 0, 0, 0
|
||||
delta, common = [], {}
|
||||
|
||||
for name in iter(old.keys()):
|
||||
if name in new:
|
||||
common[name] = 1
|
||||
|
||||
for name in old:
|
||||
if name not in common:
|
||||
remove += 1
|
||||
sz = old[name]["size"]
|
||||
down += sz
|
||||
delta.append((-sz, name))
|
||||
|
||||
for name in new:
|
||||
if name not in common:
|
||||
add += 1
|
||||
sz = new[name]["size"]
|
||||
up += sz
|
||||
delta.append((sz, name))
|
||||
|
||||
for name in common:
|
||||
d = new[name].get("size", 0) - old[name].get("size", 0)
|
||||
if d>0: grow, up = grow+1, up+d
|
||||
elif d<0: shrink, down = shrink+1, down-d
|
||||
else:
|
||||
continue
|
||||
delta.append((d, name))
|
||||
|
||||
delta.sort()
|
||||
delta.reverse()
|
||||
if flag_timing:
|
||||
end_t3 = int(time.time() * 1e9)
|
||||
|
||||
print("%-48s %7s %7s %+7s" % ("function", "old", "new", "delta"))
|
||||
for d, n in delta:
|
||||
if d:
|
||||
old_sz = old.get(n, {}).get("size", "-")
|
||||
new_sz = new.get(n, {}).get("size", "-")
|
||||
print("%-48s %7s %7s %+7d" % (n, old_sz, new_sz, d))
|
||||
print("-"*78)
|
||||
total="(add/remove: %s/%s grow/shrink: %s/%s up/down: %s/%s)%%sTotal: %s bytes"\
|
||||
% (add, remove, grow, shrink, up, -down, up-down)
|
||||
print(total % (" "*(80-len(total))))
|
||||
if flag_timing:
|
||||
print("\n%d/%d; %d Parse origin/new; processing nsecs" %
|
||||
(end_t1-start_t1, end_t2-start_t2, end_t3-start_t3))
|
||||
print("total nsecs: %d" % (end_t3-start_t1))
|
||||
41
bld/get-version
Executable file
41
bld/get-version
Executable file
@@ -0,0 +1,41 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Determine the version string to build into a binary.
|
||||
# When building in the git repository, we can use the output
|
||||
# of "git describe" which gives an unequivocal answer.
|
||||
#
|
||||
# Failing that, we use the contents of the VERSION file
|
||||
# which has a set of references substituted into it by git.
|
||||
# If we can find one which matches $v[0-9].* then we assume it's
|
||||
# a version-number tag, else we just use the whole string.
|
||||
# If there is more than one v[0-9].* tag, sort them and use the
|
||||
# first. The insane arguments to the sort command are to ensure
|
||||
# that, eg v2.64 comes before v2.63, but v2.63 comes before v2.63rc1
|
||||
# and v2.63rc1 comes before v2.63test1
|
||||
|
||||
|
||||
# Change directory to the toplevel source directory.
|
||||
if test -z "$1" || ! test -d "$1" || ! cd "$1"; then
|
||||
echo "$0: First argument $1 must be toplevel dir." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if which git >/dev/null 2>&1 && \
|
||||
([ -d .git ] || grep '^gitdir:' .git >/dev/null 2>&1) && \
|
||||
git describe >/dev/null 2>&1; then
|
||||
git describe | sed 's/^v//'
|
||||
elif grep '\$Format:%d\$' $1/VERSION >/dev/null 2>&1; then
|
||||
# unsubstituted VERSION, but no git available.
|
||||
echo UNKNOWN
|
||||
else
|
||||
vers=`cat $1/VERSION | sed 's/[(), ]/,/ g' | tr ',' '\n' | grep ^v[0-9]`
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "${vers}" | sort -k1.2,1.5Vr -k1.6,1.6 -k1.8,1.9Vr -k1.10,1.11Vr | head -n 1 | sed 's/^v//'
|
||||
else
|
||||
cat $1/VERSION
|
||||
fi
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
for f in *; do
|
||||
if [ -d $f ]; then
|
||||
install -d $1/$f/man8
|
||||
install -m 644 $f/dnsmasq.8 $1/$f/man8
|
||||
echo installing $1/$f/man8/dnsmasq.8
|
||||
$2 -m 755 -d $1/$f/man8
|
||||
$2 -m 644 $f/dnsmasq.8 $1/$f/man8
|
||||
echo installing $f/man8/dnsmasq.8
|
||||
fi
|
||||
done
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#!/bin/sh
|
||||
|
||||
for f in *.mo; do
|
||||
install -d $1/${f/.mo/}/LC_MESSAGES
|
||||
install -m 644 $f $1/${f/.mo/}/LC_MESSAGES/dnsmasq.mo
|
||||
echo installing $1/${f/.mo/}/LC_MESSAGES/dnsmasq.mo
|
||||
$2 -m 755 -d $1/${f%.mo}/LC_MESSAGES
|
||||
$2 -m 644 $f $1/${f%.mo}/LC_MESSAGES/dnsmasq.mo
|
||||
echo installing ${f%.mo}/LC_MESSAGES/dnsmasq.mo
|
||||
done
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,45 @@
|
||||
#!/bin/sh
|
||||
|
||||
if grep -q "^\#.*define.*HAVE_DBUS" config.h ; then
|
||||
exec $*
|
||||
in=`cat`
|
||||
|
||||
search()
|
||||
{
|
||||
grep "^\#[[:space:]]*define[[:space:]]*$1" config.h >/dev/null 2>&1 || \
|
||||
echo $in | grep $1 >/dev/null 2>&1
|
||||
}
|
||||
|
||||
while [ "$#" -gt 0 ]; do
|
||||
search=$1
|
||||
pkg=$2
|
||||
op=$3
|
||||
lib=$4
|
||||
shift 4
|
||||
if search "$search"; then
|
||||
|
||||
# Nasty, nasty, in --copy, arg 2 (if non-empty) is another config to search for, used with NO_GMP
|
||||
if [ $op = "--copy" ]; then
|
||||
if [ -z "$pkg" ]; then
|
||||
pkg="$lib"
|
||||
elif search "$pkg"; then
|
||||
pkg=""
|
||||
else
|
||||
pkg="$lib"
|
||||
fi
|
||||
elif search "${search}_STATIC"; then
|
||||
pkg=`$pkg --static $op $lib`
|
||||
else
|
||||
pkg=`$pkg $op $lib`
|
||||
fi
|
||||
|
||||
if search "${search}_STATIC"; then
|
||||
if [ $op = "--libs" ] || [ $op = "--copy" ]; then
|
||||
echo "-Wl,-Bstatic $pkg -Wl,-Bdynamic"
|
||||
else
|
||||
echo "$pkg"
|
||||
fi
|
||||
else
|
||||
echo "$pkg"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
done
|
||||
|
||||
36
contrib/CPE-WAN/README
Normal file
36
contrib/CPE-WAN/README
Normal file
@@ -0,0 +1,36 @@
|
||||
Dnsmasq from version 2.52 has a couple of rather application-specific
|
||||
features designed to allow for implementation of the DHCP part of CPE
|
||||
WAN management protocol.
|
||||
|
||||
http://www.broadband-forum.org/technical/download/TR-069_Amendment-2.pdf
|
||||
http://en.wikipedia.org/wiki/TR-069
|
||||
|
||||
The relevant sections are F.2.1 "Gateway Requirements" and F.2.5 "DHCP
|
||||
Vendor Options".
|
||||
|
||||
First, dnsmasq checks for DHCP requests which contain an option-125
|
||||
vendor-class option which in turn holds a vendor section for IANA
|
||||
enterprise number 3561 which contains sub-options codes 1 and 2. If
|
||||
this is present then the network-tag "cpewan-id" is set.
|
||||
This allows dnsmasq to be configured to reply with the correct
|
||||
GatewayManufacturerOUI, GatewaySerialNumber and GatewayProductClass like this:
|
||||
|
||||
dhcp-option=cpewan-id,vi-encap:3561,4,"<GatewayManufacturerOUI>"
|
||||
dhcp-option=cpewan-id,vi-encap:3561,5,"<SerialNumber>"
|
||||
dhcp-option=cpewan-id,vi-encap:3561,6,"<ProductClass>"
|
||||
|
||||
Second, the received sub-options 1, 2, and 3 are passed to the DHCP
|
||||
lease-change script as the environment variables DNSMASQ_CPEWAN_OUI,
|
||||
DNSMASQ_CPEWAN_SERIAL, and DNSMASQ_CPEWAN_CLASS respectively. This allows
|
||||
the script to be used to maintain a ManageableDevice table as
|
||||
specified in F.2.1. Note that this data is not retained in dnsmasq's
|
||||
internal DHCP lease database, so it is not available on every call to
|
||||
the script (this is the same as some other data such as vendor and
|
||||
user classes). It will however be available for at least the "add"
|
||||
call, and should be stored then against the IP address as primary
|
||||
key for future use.
|
||||
|
||||
|
||||
This feature was added to dnsmasq under sponsorship from Ericsson.
|
||||
|
||||
|
||||
38
contrib/MacOSX-launchd/launchd-README.txt
Normal file
38
contrib/MacOSX-launchd/launchd-README.txt
Normal file
@@ -0,0 +1,38 @@
|
||||
This is a launchd item for Mac OS X and Mac OS X Server.
|
||||
For more information about launchd, the
|
||||
"System wide and per-user daemon/agent manager", see the launchd
|
||||
man page, or the wikipedia page: http://en.wikipedia.org/wiki/Launchd
|
||||
|
||||
This launchd item uses the following flags:
|
||||
--keep-in-foreground - this is crucial for use with launchd
|
||||
--log-queries - this is optional and you can remove it
|
||||
--log-facility=/var/log/dnsmasq.log - again optional instead of system.log
|
||||
|
||||
To use this launchd item for dnsmasq:
|
||||
|
||||
If you don't already have a folder /Library/LaunchDaemons, then create one:
|
||||
sudo mkdir /Library/LaunchDaemons
|
||||
sudo chown root:admin /Library/LaunchDaemons
|
||||
sudo chmod 775 /Library/LaunchDaemons
|
||||
|
||||
Copy uk.org.thekelleys.dnsmasq.plist there and then set ownership/permissions:
|
||||
sudo cp uk.org.thekelleys.dnsmasq.plist /Library/LaunchDaemons/
|
||||
sudo chown root:admin /Library/LaunchDaemons/uk.org.thekelleys.dnsmasq.plist
|
||||
sudo chmod 644 /Library/LaunchDaemons/uk.org.thekelleys.dnsmasq.plist
|
||||
|
||||
Optionally, edit your dnsmasq configuration file to your liking.
|
||||
|
||||
To start the launchd job, which starts dnsmasq, reboot or use the command:
|
||||
sudo launchctl load /Library/LaunchDaemons/uk.org.thekelleys.dnsmasq.plist
|
||||
|
||||
To stop the launchd job, which stops dnsmasq, use the command:
|
||||
sudo launchctl unload /Library/LaunchDaemons/uk.org.thekelleys.dnsmasq.plist
|
||||
|
||||
If you want to permanently stop the launchd job, so it doesn't start the job even after a reboot, use the following command:
|
||||
sudo launchctl unload -w /Library/LaunchDaemons/uk.org.thekelleys.dnsmasq.plist
|
||||
|
||||
If you make a change to the configuration file, you should relaunch dnsmasq;
|
||||
to do this unload and then load again:
|
||||
|
||||
sudo launchctl unload /Library/LaunchDaemons/uk.org.thekelleys.dnsmasq.plist
|
||||
sudo launchctl load /Library/LaunchDaemons/uk.org.thekelleys.dnsmasq.plist
|
||||
15
contrib/MacOSX-launchd/uk.org.thekelleys.dnsmasq.plist
Normal file
15
contrib/MacOSX-launchd/uk.org.thekelleys.dnsmasq.plist
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Label</key>
|
||||
<string>uk.org.thekelleys.dnsmasq</string>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>/usr/local/sbin/dnsmasq</string>
|
||||
<string>--keep-in-foreground</string>
|
||||
</array>
|
||||
<key>RunAtLoad</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
28
contrib/Solaris10/README
Normal file
28
contrib/Solaris10/README
Normal file
@@ -0,0 +1,28 @@
|
||||
From: David Connelly <dconnelly@gmail.com>
|
||||
Date: Mon, Apr 7, 2008 at 3:31 AM
|
||||
Subject: Solaris 10 service manifest
|
||||
To: dnsmasq-discuss@lists.thekelleys.org.uk
|
||||
|
||||
|
||||
I've found dnsmasq much easier to set up on my home server running Solaris
|
||||
10 than the stock dhcp/dns server, which is probably overkill anyway for my
|
||||
simple home network needs. Since Solaris now uses SMF (Service Management
|
||||
Facility) to manage services I thought I'd create a simple service manifest
|
||||
for the dnsmasq service. The manifest currently assumes that dnsmasq has
|
||||
been installed in '/usr/local/sbin/dnsmasq' and the configuration file in
|
||||
'/usr/local/etc/dnsmasq.conf', so you may have to adjust these paths for
|
||||
your local installation. Here are the steps I followed to install and enable
|
||||
the dnsmasq service:
|
||||
# svccfg import dnsmasq.xml
|
||||
# svcadm enable dnsmasq
|
||||
|
||||
To confirm that the service is enabled and online:
|
||||
|
||||
# svcs -l dnsmasq
|
||||
|
||||
I've just started learning about SMF so if anyone has any
|
||||
corrections/feedback they are more than welcome.
|
||||
|
||||
Thanks,
|
||||
David
|
||||
|
||||
8
contrib/Solaris10/README-sparc
Normal file
8
contrib/Solaris10/README-sparc
Normal file
@@ -0,0 +1,8 @@
|
||||
Hi Simon,
|
||||
|
||||
I just wanted to let you know that I have built a Solaris .pkg install package of your dnsmasq utility for people to use. Feel free to point them in my direction if you have people who want this sort of thing.
|
||||
|
||||
http://ejesconsulting.wordpress.com/2010/05/12/gnu-dnsmasq-for-opensolaris-sparc/
|
||||
|
||||
Thanks
|
||||
-evan
|
||||
25
contrib/Solaris10/README.create_package
Normal file
25
contrib/Solaris10/README.create_package
Normal file
@@ -0,0 +1,25 @@
|
||||
Ok, script attached ... seems to be working ok for me,
|
||||
tried to install and remove a few times. It does the
|
||||
right thing with the smf when installing, you can then
|
||||
simply enable the service. Upon removal it cleans up the
|
||||
files but won't clean up the services (I think until
|
||||
a reboot) ... I've only started looking at the new
|
||||
packages stuff in the last day or two, so I could be
|
||||
missing something, but I can't find any way to force
|
||||
a proper cleanup.
|
||||
|
||||
It requires that you have a writable repository setup
|
||||
as per the docs on the opensolaris website and it will
|
||||
create a dnsmasq package (package name is a variable
|
||||
in the script). The script takes a version number for
|
||||
the package and assumes that it's in the contrib/Solaris10
|
||||
directory, it then works out the base tree directory
|
||||
from $0.
|
||||
|
||||
i.e. $ contrib/Solaris10/create_package 2.52-1
|
||||
or $ cd contrib/Solaris10; ./create_package 2.52-1
|
||||
|
||||
It's a bit more complex than it could be because I
|
||||
prefer putting the daemon in /usr/sbin and the config
|
||||
in /etc, so the script will actually create a new
|
||||
version of the existing contrib dnsmasq.xml.
|
||||
87
contrib/Solaris10/create_package
Normal file
87
contrib/Solaris10/create_package
Normal file
@@ -0,0 +1,87 @@
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# For our package, and for the SMF script, we need to define where we
|
||||
# want things to go...
|
||||
#
|
||||
BIN_DIR="/usr/sbin"
|
||||
CONF_DIR="/etc"
|
||||
MAN_DIR="/usr/share/man/man8"
|
||||
|
||||
PACKAGE_NAME="dnsmasq"
|
||||
|
||||
#
|
||||
# Since we know we are in the contrib directory we can work out where
|
||||
# the rest of the tree is...
|
||||
#
|
||||
BASEDIR="`dirname $0`/../.."
|
||||
|
||||
#
|
||||
# We need a version number to use for the package creation...
|
||||
#
|
||||
if [ $# != 1 ]; then
|
||||
echo "Usage: $0 <package_version_number>" >&2
|
||||
exit 1
|
||||
fi
|
||||
VERSION="$1"
|
||||
|
||||
#
|
||||
# First thing we do is fix-up the smf file to use the paths we prefer...
|
||||
#
|
||||
if [ ! -f "${BASEDIR}/contrib/Solaris10/dnsmasq.xml" ]; then
|
||||
echo "$0: unable to find contrib/Solaris10/dnsmasq.xml" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Fixing up smf file ... \c"
|
||||
cat "${BASEDIR}/contrib/Solaris10/dnsmasq.xml" | \
|
||||
sed -e "s%/usr/local/etc%${CONF_DIR}%" \
|
||||
-e "s%/usr/local/sbin%${BIN_DIR}%" \
|
||||
-e "s%/usr/local/man%${MAN_DIR}%" > ${BASEDIR}/contrib/Solaris10/dnsmasq-pkg.xml
|
||||
echo "done."
|
||||
|
||||
echo "Creating packaging file ... \c"
|
||||
cat <<EOF >${BASEDIR}/contrib/Solaris10/dnsmasq_package.inc
|
||||
#
|
||||
# header
|
||||
#
|
||||
set name=pkg.name value="dnsmasq"
|
||||
set name=pkg.description value="dnsmasq daemon - dns, dhcp, tftp etc"
|
||||
set name=pkg.detailed_url value="http://www.thekelleys.org.uk/dnsmasq/doc.html"
|
||||
set name=info.maintainer value="TBD (tbd@tbd.com)"
|
||||
set name=info.upstream value="dnsmasq-discuss@lists.thekelleys.org.uk"
|
||||
set name=info.upstream_url value="http://www.thekelleys.org.uk/dnsmasq/doc.html"
|
||||
#
|
||||
# dependencies ... none?
|
||||
#
|
||||
|
||||
#
|
||||
# directories
|
||||
#
|
||||
dir mode=0755 owner=root group=bin path=${BIN_DIR}/
|
||||
dir mode=0755 owner=root group=sys path=${CONF_DIR}/
|
||||
dir mode=0755 owner=root group=sys path=${MAN_DIR}/
|
||||
dir mode=0755 owner=root group=sys path=/var/
|
||||
dir mode=0755 owner=root group=sys path=/var/svc
|
||||
dir mode=0755 owner=root group=sys path=/var/svc/manifest
|
||||
dir mode=0755 owner=root group=sys path=/var/svc/manifest/network
|
||||
|
||||
#
|
||||
# files
|
||||
#
|
||||
file ${BASEDIR}/src/dnsmasq mode=0555 owner=root group=bin path=${BIN_DIR}/dnsmasq
|
||||
file ${BASEDIR}/man/dnsmasq.8 mode=0555 owner=root group=bin path=${MAN_DIR}/dnsmasq.8
|
||||
file ${BASEDIR}/dnsmasq.conf.example mode=0644 owner=root group=sys path=${CONF_DIR}/dnsmasq.conf preserve=strawberry
|
||||
file ${BASEDIR}/contrib/Solaris10/dnsmasq-pkg.xml mode=0644 owner=root group=sys path=/var/svc/manifest/network/dnsmasq.xml restart_fmri=svc:/system/manifest-import:default
|
||||
|
||||
EOF
|
||||
echo "done."
|
||||
|
||||
echo "Creating package..."
|
||||
eval `pkgsend open ${PACKAGE_NAME}@${VERSION}`
|
||||
pkgsend include ${BASEDIR}/contrib/Solaris10/dnsmasq_package.inc
|
||||
if [ "$?" = 0 ]; then
|
||||
pkgsend close
|
||||
else
|
||||
echo "Errors"
|
||||
fi
|
||||
65
contrib/Solaris10/dnsmasq.xml
Normal file
65
contrib/Solaris10/dnsmasq.xml
Normal file
@@ -0,0 +1,65 @@
|
||||
<?xml version='1.0'?>
|
||||
<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
|
||||
|
||||
<!-- Service manifest for dnsmasq -->
|
||||
|
||||
<service_bundle type='manifest' name='dnsmasq'>
|
||||
<service name='network/dnsmasq' type='service' version='1'>
|
||||
|
||||
<create_default_instance enabled='false'/>
|
||||
<single_instance/>
|
||||
|
||||
<dependency name='multi-user'
|
||||
grouping='require_all'
|
||||
restart_on='refresh'
|
||||
type='service'>
|
||||
<service_fmri value='svc:/milestone/multi-user'/>
|
||||
</dependency>
|
||||
|
||||
<dependency name='config'
|
||||
grouping='require_all'
|
||||
restart_on='restart'
|
||||
type='path'>
|
||||
<service_fmri value='file:///usr/local/etc/dnsmasq.conf'/>
|
||||
</dependency>
|
||||
|
||||
<dependent name='dnsmasq_multi-user-server'
|
||||
grouping='optional_all'
|
||||
restart_on='none'>
|
||||
<service_fmri value='svc:/milestone/multi-user-server' />
|
||||
</dependent>
|
||||
|
||||
<exec_method type='method' name='start'
|
||||
exec='/usr/local/sbin/dnsmasq -C /usr/local/etc/dnsmasq.conf'
|
||||
timeout_seconds='60' >
|
||||
<method_context>
|
||||
<method_credential user='root' group='root' privileges='all'/>
|
||||
</method_context>
|
||||
</exec_method>
|
||||
|
||||
<exec_method type='method'
|
||||
name='stop'
|
||||
exec=':kill'
|
||||
timeout_seconds='60'/>
|
||||
|
||||
<exec_method type='method'
|
||||
name='refresh'
|
||||
exec=':kill -HUP'
|
||||
timeout_seconds='60' />
|
||||
|
||||
<template>
|
||||
<common_name>
|
||||
<loctext xml:lang='C'>dnsmasq server</loctext>
|
||||
</common_name>
|
||||
<description>
|
||||
<loctext xml:lang='C'>
|
||||
dnsmasq - A lightweight DHCP and caching DNS server.
|
||||
</loctext>
|
||||
</description>
|
||||
<documentation>
|
||||
<manpage title='dnsmasq' section='8' manpath='/usr/local/man'/>
|
||||
</documentation>
|
||||
</template>
|
||||
|
||||
</service>
|
||||
</service_bundle>
|
||||
54
contrib/conntrack/README
Normal file
54
contrib/conntrack/README
Normal file
@@ -0,0 +1,54 @@
|
||||
Linux iptables includes that ability to mark individual network packets
|
||||
with a "firewall mark". Additionally there is a component called
|
||||
"conntrack" which tries to string sequences of related packets together
|
||||
into a "connection" (it even relates sequences of UDP and ICMP packets).
|
||||
There is a related mark for a connection called a "connection mark".
|
||||
Marks can be copied freely between the firewall and connection marks
|
||||
|
||||
Using these two features it become possible to tag all related traffic
|
||||
in arbitrary ways, eg authenticated users, traffic from a particular IP,
|
||||
port, etc. Unfortunately any kind of "proxy" breaks this relationship
|
||||
because network packets go in one side of the proxy and a completely new
|
||||
connection comes out of the other side. However, sometimes, we want to
|
||||
maintain that relationship through the proxy and continue the connection
|
||||
mark on packets upstream of our proxy
|
||||
|
||||
Dnsmasq includes such a feature enabled by the --conntrack
|
||||
option. This allows, for example, using iptables to mark traffic from
|
||||
a particular IP, and that mark to be persisted to requests made *by*
|
||||
Dnsmasq. Such a feature could be useful for bandwidth accounting,
|
||||
captive portals and the like. Note a similar feature has been
|
||||
implemented in Squid 2.2
|
||||
|
||||
|
||||
As an example consider the following iptables rules:
|
||||
|
||||
|
||||
1) iptables -t mangle -A PREROUTING -j CONNMARK --restore-mark
|
||||
2) iptables -t mangle -A PREROUTING -m mark --mark 0 -s 192.168.111.137
|
||||
-j MARK --set-mark 137
|
||||
3) iptables -t mangle -A PREROUTING -j CONNMARK --save-mark
|
||||
|
||||
4) iptables -t mangle -A OUTPUT -m mark ! --mark 0 -j CONNMARK --save-mark
|
||||
|
||||
1-3) are all applied to the PREROUTING table and affect all packets
|
||||
entering the firewall.
|
||||
|
||||
1) copies any existing connection mark into the firewall mark. 2) Checks
|
||||
the packet not already marked and if not applies an arbitrary mark based
|
||||
on IP address. 3) Saves the firewall mark back to the connection mark
|
||||
(which will persist it across related packets)
|
||||
|
||||
4) is applied to the OUTPUT table, which is where we first see packets
|
||||
generated locally. Dnsmasq will have already copied the firewall mark
|
||||
from the request, across to the new packet, and so all that remains is
|
||||
for iptables to copy it to the connection mark so it's persisted across
|
||||
packets.
|
||||
|
||||
Note: iptables can be quite confusing to the beginner. The following
|
||||
diagram is extremely helpful in understanding the flows
|
||||
http://linux-ip.net/nf/nfk-traversal.png
|
||||
Additionally the following URL contains a useful "starting guide" on
|
||||
linux connection tracking/marking
|
||||
http://home.regit.org/netfilter-en/netfilter-connmark/
|
||||
|
||||
43
contrib/dbus-test/dbus-test.py
Executable file
43
contrib/dbus-test/dbus-test.py
Executable file
@@ -0,0 +1,43 @@
|
||||
#!/usr/bin/python
|
||||
import dbus
|
||||
|
||||
bus = dbus.SystemBus()
|
||||
p = bus.get_object("uk.org.thekelleys.dnsmasq", "/uk/org/thekelleys/dnsmasq")
|
||||
l = dbus.Interface(p, dbus_interface="uk.org.thekelleys.dnsmasq")
|
||||
|
||||
# The new more flexible SetServersEx method
|
||||
array = dbus.Array()
|
||||
array.append(["1.2.3.5"])
|
||||
array.append(["1.2.3.4#664", "foobar.com"])
|
||||
array.append(["1003:1234:abcd::1%eth0", "eng.mycorp.com", "lab.mycorp.com"])
|
||||
print l.SetServersEx(array)
|
||||
|
||||
# Must create a new object for dnsmasq as the introspection gives the wrong
|
||||
# signature for SetServers (av) while the code only expects a bunch of arguments
|
||||
# instead of an array of variants
|
||||
p = bus.get_object("uk.org.thekelleys.dnsmasq", "/uk/org/thekelleys/dnsmasq", introspect=False)
|
||||
l = dbus.Interface(p, dbus_interface="uk.org.thekelleys.dnsmasq")
|
||||
|
||||
# The previous method; all addresses in machine byte order
|
||||
print l.SetServers(dbus.UInt32(16909060), # 1.2.3.5
|
||||
dbus.UInt32(16909061), # 1.2.3.4
|
||||
"foobar.com",
|
||||
dbus.Byte(0x10), # 1003:1234:abcd::1
|
||||
dbus.Byte(0x03),
|
||||
dbus.Byte(0x12),
|
||||
dbus.Byte(0x34),
|
||||
dbus.Byte(0xab),
|
||||
dbus.Byte(0xcd),
|
||||
dbus.Byte(0x00),
|
||||
dbus.Byte(0x00),
|
||||
dbus.Byte(0x00),
|
||||
dbus.Byte(0x00),
|
||||
dbus.Byte(0x00),
|
||||
dbus.Byte(0x00),
|
||||
dbus.Byte(0x00),
|
||||
dbus.Byte(0x00),
|
||||
dbus.Byte(0x00),
|
||||
dbus.Byte(0x01),
|
||||
"eng.mycorp.com",
|
||||
"lab.mycorp.com")
|
||||
|
||||
12
contrib/dns-loc/README
Normal file
12
contrib/dns-loc/README
Normal file
@@ -0,0 +1,12 @@
|
||||
Hi Simon
|
||||
|
||||
Here is a patch against dnsmasq 2.39 which provides support for LOC
|
||||
entries in order to assign location information to dns records
|
||||
(rfc1876). I tested it on OSX and on OpenWRT.
|
||||
|
||||
Cheers
|
||||
Lorenz
|
||||
|
||||
More info:
|
||||
http://www.ckdhr.com/dns-loc/
|
||||
http://www.faqs.org/rfcs/rfc1876.html
|
||||
522
contrib/dns-loc/dnsmasq2-loc-rfc1876.patch
Normal file
522
contrib/dns-loc/dnsmasq2-loc-rfc1876.patch
Normal file
@@ -0,0 +1,522 @@
|
||||
diff -Nur dnsmasq-2.39-orig/bld/Makefile dnsmasq-2.39/bld/Makefile
|
||||
--- dnsmasq-2.39-orig/bld/Makefile 2007-02-17 14:37:06.000000000 +0100
|
||||
+++ dnsmasq-2.39/bld/Makefile 2007-05-20 18:23:44.000000000 +0200
|
||||
@@ -2,7 +2,7 @@
|
||||
PKG_CONFIG ?= pkg-config
|
||||
|
||||
|
||||
-OBJS = cache.o rfc1035.o util.o option.o forward.o isc.o network.o \
|
||||
+OBJS = cache.o rfc1035.o rfc1876.o util.o option.o forward.o isc.o network.o \
|
||||
dnsmasq.o dhcp.o lease.o rfc2131.o netlink.o dbus.o bpf.o \
|
||||
helper.o tftp.o log.o
|
||||
|
||||
diff -Nur dnsmasq-2.39-orig/src/dnsmasq.h dnsmasq-2.39/src/dnsmasq.h
|
||||
--- dnsmasq-2.39-orig/src/dnsmasq.h 2007-04-20 12:53:38.000000000 +0200
|
||||
+++ dnsmasq-2.39/src/dnsmasq.h 2007-05-20 19:50:37.000000000 +0200
|
||||
@@ -162,6 +162,12 @@
|
||||
struct interface_name *next;
|
||||
};
|
||||
|
||||
+struct loc_record {
|
||||
+ char *name, loc[16];
|
||||
+ unsigned short class;
|
||||
+ struct loc_record *next;
|
||||
+};
|
||||
+
|
||||
union bigname {
|
||||
char name[MAXDNAME];
|
||||
union bigname *next; /* freelist */
|
||||
@@ -476,6 +482,7 @@
|
||||
struct mx_srv_record *mxnames;
|
||||
struct txt_record *txt;
|
||||
struct ptr_record *ptr;
|
||||
+ struct loc_record *loc;
|
||||
struct interface_name *int_names;
|
||||
char *mxtarget;
|
||||
char *lease_file;
|
||||
@@ -725,3 +732,6 @@
|
||||
void tftp_request(struct listener *listen, struct daemon *daemon, time_t now);
|
||||
void check_tftp_listeners(struct daemon *daemon, fd_set *rset, time_t now);
|
||||
#endif
|
||||
+
|
||||
+/* rfc1876 */
|
||||
+u_int32_t loc_aton(const char *ascii, u_char *binary);
|
||||
diff -Nur dnsmasq-2.39-orig/src/option.c dnsmasq-2.39/src/option.c
|
||||
--- dnsmasq-2.39-orig/src/option.c 2007-04-19 23:34:49.000000000 +0200
|
||||
+++ dnsmasq-2.39/src/option.c 2007-05-20 20:15:15.000000000 +0200
|
||||
@@ -43,6 +43,7 @@
|
||||
#define LOPT_REMOTE 269
|
||||
#define LOPT_SUBSCR 270
|
||||
#define LOPT_INTNAME 271
|
||||
+#define LOPT_LOC 272
|
||||
|
||||
#ifdef HAVE_GETOPT_LONG
|
||||
static const struct option opts[] =
|
||||
@@ -122,6 +123,7 @@
|
||||
{"tftp-root", 1, 0, LOPT_PREFIX },
|
||||
{"tftp-max", 1, 0, LOPT_TFTP_MAX },
|
||||
{"ptr-record", 1, 0, LOPT_PTR },
|
||||
+ {"loc-record", 1, 0, LOPT_LOC },
|
||||
#if defined(__FreeBSD__) || defined(__DragonFly__)
|
||||
{"bridge-interface", 1, 0 , LOPT_BRIDGE },
|
||||
#endif
|
||||
@@ -235,6 +237,7 @@
|
||||
{ "-y, --localise-queries", gettext_noop("Answer DNS queries based on the interface a query was sent to."), NULL },
|
||||
{ "-Y --txt-record=name,txt....", gettext_noop("Specify TXT DNS record."), NULL },
|
||||
{ " --ptr-record=name,target", gettext_noop("Specify PTR DNS record."), NULL },
|
||||
+ { " --loc-record=name,lat lon alt", gettext_noop("Specify LOC DNS record."), NULL },
|
||||
{ " --interface-name=name,interface", gettext_noop("Give DNS name to IPv4 address of interface."), NULL },
|
||||
{ "-z, --bind-interfaces", gettext_noop("Bind only to interfaces in use."), NULL },
|
||||
{ "-Z, --read-ethers", gettext_noop("Read DHCP static host information from %s."), ETHERSFILE },
|
||||
@@ -1835,6 +1838,37 @@
|
||||
new->intr = safe_string_alloc(comma);
|
||||
break;
|
||||
}
|
||||
+
|
||||
+ case LOPT_LOC:
|
||||
+ {
|
||||
+ struct loc_record *new;
|
||||
+ unsigned char *p, *q;
|
||||
+
|
||||
+ comma = split(arg);
|
||||
+
|
||||
+ if (!canonicalise_opt(arg))
|
||||
+ {
|
||||
+ option = '?';
|
||||
+ problem = _("bad LOC record");
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ new = safe_malloc(sizeof(struct loc_record));
|
||||
+ new->next = daemon->loc;
|
||||
+ daemon->loc = new;
|
||||
+ new->class = C_IN;
|
||||
+ if (!comma || loc_aton(comma,new->loc)!=16)
|
||||
+ {
|
||||
+ option = '?';
|
||||
+ problem = _("bad LOC record");
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (comma)
|
||||
+ *comma = 0;
|
||||
+ new->name = safe_string_alloc(arg);
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
case LOPT_PTR: /* --ptr-record */
|
||||
{
|
||||
diff -Nur dnsmasq-2.39-orig/src/rfc1035.c dnsmasq-2.39/src/rfc1035.c
|
||||
--- dnsmasq-2.39-orig/src/rfc1035.c 2007-04-20 12:54:26.000000000 +0200
|
||||
+++ dnsmasq-2.39/src/rfc1035.c 2007-05-20 18:22:46.000000000 +0200
|
||||
@@ -1112,6 +1112,27 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ if (qtype == T_LOC || qtype == T_ANY)
|
||||
+ {
|
||||
+ struct loc_record *t;
|
||||
+ for(t = daemon->loc; t ; t = t->next)
|
||||
+ {
|
||||
+ if (t->class == qclass && hostname_isequal(name, t->name))
|
||||
+ {
|
||||
+ ans = 1;
|
||||
+ if (!dryrun)
|
||||
+ {
|
||||
+ log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL, 0, NULL, 0);
|
||||
+ if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
||||
+ daemon->local_ttl, NULL,
|
||||
+ T_LOC, t->class, "t", 16, t->loc))
|
||||
+ anscount++;
|
||||
+
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (qclass == C_IN)
|
||||
{
|
||||
if (qtype == T_PTR || qtype == T_ANY)
|
||||
diff -Nur dnsmasq-2.39-orig/src/rfc1876.c dnsmasq-2.39/src/rfc1876.c
|
||||
--- dnsmasq-2.39-orig/src/rfc1876.c 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ dnsmasq-2.39/src/rfc1876.c 2007-05-20 19:50:10.000000000 +0200
|
||||
@@ -0,0 +1,379 @@
|
||||
+/*
|
||||
+ * routines to convert between on-the-wire RR format and zone file
|
||||
+ * format. Does not contain conversion to/from decimal degrees;
|
||||
+ * divide or multiply by 60*60*1000 for that.
|
||||
+ */
|
||||
+
|
||||
+#include "dnsmasq.h"
|
||||
+
|
||||
+static unsigned int poweroften[10] = {1, 10, 100, 1000, 10000, 100000,
|
||||
+ 1000000,10000000,100000000,1000000000};
|
||||
+
|
||||
+/* takes an XeY precision/size value, returns a string representation.*/
|
||||
+static const char *
|
||||
+precsize_ntoa(u_int8_t prec)
|
||||
+{
|
||||
+ static char retbuf[sizeof("90000000.00")];
|
||||
+ unsigned long val;
|
||||
+ int mantissa, exponent;
|
||||
+
|
||||
+ mantissa = (int)((prec >> 4) & 0x0f) % 10;
|
||||
+ exponent = (int)((prec >> 0) & 0x0f) % 10;
|
||||
+
|
||||
+ val = mantissa * poweroften[exponent];
|
||||
+
|
||||
+ (void) sprintf(retbuf,"%d.%.2d", val/100, val%100);
|
||||
+ return (retbuf);
|
||||
+}
|
||||
+
|
||||
+/* converts ascii size/precision X * 10**Y(cm) to 0xXY. moves pointer.*/
|
||||
+static u_int8_t
|
||||
+precsize_aton(char **strptr)
|
||||
+{
|
||||
+ unsigned int mval = 0, cmval = 0;
|
||||
+ u_int8_t retval = 0;
|
||||
+ register char *cp;
|
||||
+ register int exponent;
|
||||
+ register int mantissa;
|
||||
+
|
||||
+ cp = *strptr;
|
||||
+
|
||||
+ while (isdigit(*cp))
|
||||
+ mval = mval * 10 + (*cp++ - '0');
|
||||
+
|
||||
+ if (*cp == '.') { /* centimeters */
|
||||
+ cp++;
|
||||
+ if (isdigit(*cp)) {
|
||||
+ cmval = (*cp++ - '0') * 10;
|
||||
+ if (isdigit(*cp)) {
|
||||
+ cmval += (*cp++ - '0');
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ cmval = (mval * 100) + cmval;
|
||||
+
|
||||
+ for (exponent = 0; exponent < 9; exponent++)
|
||||
+ if (cmval < poweroften[exponent+1])
|
||||
+ break;
|
||||
+
|
||||
+ mantissa = cmval / poweroften[exponent];
|
||||
+ if (mantissa > 9)
|
||||
+ mantissa = 9;
|
||||
+
|
||||
+ retval = (mantissa << 4) | exponent;
|
||||
+
|
||||
+ *strptr = cp;
|
||||
+
|
||||
+ return (retval);
|
||||
+}
|
||||
+
|
||||
+/* converts ascii lat/lon to unsigned encoded 32-bit number.
|
||||
+ * moves pointer. */
|
||||
+static u_int32_t
|
||||
+latlon2ul(char **latlonstrptr,int *which)
|
||||
+{
|
||||
+ register char *cp;
|
||||
+ u_int32_t retval;
|
||||
+ int deg = 0, min = 0, secs = 0, secsfrac = 0;
|
||||
+
|
||||
+ cp = *latlonstrptr;
|
||||
+
|
||||
+ while (isdigit(*cp))
|
||||
+ deg = deg * 10 + (*cp++ - '0');
|
||||
+
|
||||
+ while (isspace(*cp))
|
||||
+ cp++;
|
||||
+
|
||||
+ if (!(isdigit(*cp)))
|
||||
+ goto fndhemi;
|
||||
+
|
||||
+ while (isdigit(*cp))
|
||||
+ min = min * 10 + (*cp++ - '0');
|
||||
+ while (isspace(*cp))
|
||||
+ cp++;
|
||||
+
|
||||
+ if (!(isdigit(*cp)))
|
||||
+ goto fndhemi;
|
||||
+
|
||||
+ while (isdigit(*cp))
|
||||
+ secs = secs * 10 + (*cp++ - '0');
|
||||
+
|
||||
+ if (*cp == '.') { /* decimal seconds */
|
||||
+ cp++;
|
||||
+ if (isdigit(*cp)) {
|
||||
+ secsfrac = (*cp++ - '0') * 100;
|
||||
+ if (isdigit(*cp)) {
|
||||
+ secsfrac += (*cp++ - '0') * 10;
|
||||
+ if (isdigit(*cp)) {
|
||||
+ secsfrac += (*cp++ - '0');
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ while (!isspace(*cp)) /* if any trailing garbage */
|
||||
+ cp++;
|
||||
+
|
||||
+ while (isspace(*cp))
|
||||
+ cp++;
|
||||
+
|
||||
+ fndhemi:
|
||||
+ switch (*cp) {
|
||||
+ case 'N': case 'n':
|
||||
+ case 'E': case 'e':
|
||||
+ retval = ((unsigned)1<<31)
|
||||
+ + (((((deg * 60) + min) * 60) + secs) * 1000)
|
||||
+ + secsfrac;
|
||||
+ break;
|
||||
+ case 'S': case 's':
|
||||
+ case 'W': case 'w':
|
||||
+ retval = ((unsigned)1<<31)
|
||||
+ - (((((deg * 60) + min) * 60) + secs) * 1000)
|
||||
+ - secsfrac;
|
||||
+ break;
|
||||
+ default:
|
||||
+ retval = 0; /* invalid value -- indicates error */
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ switch (*cp) {
|
||||
+ case 'N': case 'n':
|
||||
+ case 'S': case 's':
|
||||
+ *which = 1; /* latitude */
|
||||
+ break;
|
||||
+ case 'E': case 'e':
|
||||
+ case 'W': case 'w':
|
||||
+ *which = 2; /* longitude */
|
||||
+ break;
|
||||
+ default:
|
||||
+ *which = 0; /* error */
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ cp++; /* skip the hemisphere */
|
||||
+
|
||||
+ while (!isspace(*cp)) /* if any trailing garbage */
|
||||
+ cp++;
|
||||
+
|
||||
+ while (isspace(*cp)) /* move to next field */
|
||||
+ cp++;
|
||||
+
|
||||
+ *latlonstrptr = cp;
|
||||
+
|
||||
+ return (retval);
|
||||
+}
|
||||
+
|
||||
+/* converts a zone file representation in a string to an RDATA
|
||||
+ * on-the-wire representation. */
|
||||
+u_int32_t
|
||||
+loc_aton(const char *ascii, u_char *binary)
|
||||
+{
|
||||
+ const char *cp, *maxcp;
|
||||
+ u_char *bcp;
|
||||
+
|
||||
+ u_int32_t latit = 0, longit = 0, alt = 0;
|
||||
+ u_int32_t lltemp1 = 0, lltemp2 = 0;
|
||||
+ int altmeters = 0, altfrac = 0, altsign = 1;
|
||||
+ u_int8_t hp = 0x16; /* default = 1e6 cm = 10000.00m = 10km */
|
||||
+ u_int8_t vp = 0x13; /* default = 1e3 cm = 10.00m */
|
||||
+ u_int8_t siz = 0x12; /* default = 1e2 cm = 1.00m */
|
||||
+ int which1 = 0, which2 = 0;
|
||||
+
|
||||
+ cp = ascii;
|
||||
+ maxcp = cp + strlen(ascii);
|
||||
+
|
||||
+ lltemp1 = latlon2ul(&cp, &which1);
|
||||
+ lltemp2 = latlon2ul(&cp, &which2);
|
||||
+
|
||||
+ switch (which1 + which2) {
|
||||
+ case 3: /* 1 + 2, the only valid combination */
|
||||
+ if ((which1 == 1) && (which2 == 2)) { /* normal case */
|
||||
+ latit = lltemp1;
|
||||
+ longit = lltemp2;
|
||||
+ } else if ((which1 == 2) && (which2 == 1)) {/*reversed*/
|
||||
+ longit = lltemp1;
|
||||
+ latit = lltemp2;
|
||||
+ } else { /* some kind of brokenness */
|
||||
+ return 0;
|
||||
+ }
|
||||
+ break;
|
||||
+ default: /* we didn't get one of each */
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ /* altitude */
|
||||
+ if (*cp == '-') {
|
||||
+ altsign = -1;
|
||||
+ cp++;
|
||||
+ }
|
||||
+
|
||||
+ if (*cp == '+')
|
||||
+ cp++;
|
||||
+
|
||||
+ while (isdigit(*cp))
|
||||
+ altmeters = altmeters * 10 + (*cp++ - '0');
|
||||
+
|
||||
+ if (*cp == '.') { /* decimal meters */
|
||||
+ cp++;
|
||||
+ if (isdigit(*cp)) {
|
||||
+ altfrac = (*cp++ - '0') * 10;
|
||||
+ if (isdigit(*cp)) {
|
||||
+ altfrac += (*cp++ - '0');
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ alt = (10000000 + (altsign * (altmeters * 100 + altfrac)));
|
||||
+
|
||||
+ while (!isspace(*cp) && (cp < maxcp))
|
||||
+ /* if trailing garbage or m */
|
||||
+ cp++;
|
||||
+
|
||||
+ while (isspace(*cp) && (cp < maxcp))
|
||||
+ cp++;
|
||||
+ if (cp >= maxcp)
|
||||
+ goto defaults;
|
||||
+
|
||||
+ siz = precsize_aton(&cp);
|
||||
+
|
||||
+ while (!isspace(*cp) && (cp < maxcp))/*if trailing garbage or m*/
|
||||
+ cp++;
|
||||
+
|
||||
+ while (isspace(*cp) && (cp < maxcp))
|
||||
+ cp++;
|
||||
+
|
||||
+ if (cp >= maxcp)
|
||||
+ goto defaults;
|
||||
+
|
||||
+ hp = precsize_aton(&cp);
|
||||
+
|
||||
+ while (!isspace(*cp) && (cp < maxcp))/*if trailing garbage or m*/
|
||||
+ cp++;
|
||||
+
|
||||
+ while (isspace(*cp) && (cp < maxcp))
|
||||
+ cp++;
|
||||
+
|
||||
+ if (cp >= maxcp)
|
||||
+ goto defaults;
|
||||
+
|
||||
+ vp = precsize_aton(&cp);
|
||||
+
|
||||
+ defaults:
|
||||
+
|
||||
+ bcp = binary;
|
||||
+ *bcp++ = (u_int8_t) 0; /* version byte */
|
||||
+ *bcp++ = siz;
|
||||
+ *bcp++ = hp;
|
||||
+ *bcp++ = vp;
|
||||
+ PUTLONG(latit,bcp);
|
||||
+ PUTLONG(longit,bcp);
|
||||
+ PUTLONG(alt,bcp);
|
||||
+
|
||||
+ return (16); /* size of RR in octets */
|
||||
+}
|
||||
+
|
||||
+/* takes an on-the-wire LOC RR and prints it in zone file
|
||||
+ * (human readable) format. */
|
||||
+char *
|
||||
+loc_ntoa(const u_char *binary,char *ascii)
|
||||
+{
|
||||
+ static char tmpbuf[255*3];
|
||||
+
|
||||
+ register char *cp;
|
||||
+ register const u_char *rcp;
|
||||
+
|
||||
+ int latdeg, latmin, latsec, latsecfrac;
|
||||
+ int longdeg, longmin, longsec, longsecfrac;
|
||||
+ char northsouth, eastwest;
|
||||
+ int altmeters, altfrac, altsign;
|
||||
+
|
||||
+ const int referencealt = 100000 * 100;
|
||||
+
|
||||
+ int32_t latval, longval, altval;
|
||||
+ u_int32_t templ;
|
||||
+ u_int8_t sizeval, hpval, vpval, versionval;
|
||||
+
|
||||
+ char *sizestr, *hpstr, *vpstr;
|
||||
+
|
||||
+ rcp = binary;
|
||||
+ if (ascii)
|
||||
+ cp = ascii;
|
||||
+ else {
|
||||
+ cp = tmpbuf;
|
||||
+ }
|
||||
+
|
||||
+ versionval = *rcp++;
|
||||
+
|
||||
+ if (versionval) {
|
||||
+ sprintf(cp,"; error: unknown LOC RR version");
|
||||
+ return (cp);
|
||||
+ }
|
||||
+
|
||||
+ sizeval = *rcp++;
|
||||
+
|
||||
+ hpval = *rcp++;
|
||||
+ vpval = *rcp++;
|
||||
+
|
||||
+ GETLONG(templ,rcp);
|
||||
+ latval = (templ - ((unsigned)1<<31));
|
||||
+
|
||||
+ GETLONG(templ,rcp);
|
||||
+ longval = (templ - ((unsigned)1<<31));
|
||||
+
|
||||
+ GETLONG(templ,rcp);
|
||||
+ if (templ < referencealt) { /* below WGS 84 spheroid */
|
||||
+ altval = referencealt - templ;
|
||||
+ altsign = -1;
|
||||
+ } else {
|
||||
+ altval = templ - referencealt;
|
||||
+ altsign = 1;
|
||||
+ }
|
||||
+
|
||||
+ if (latval < 0) {
|
||||
+ northsouth = 'S';
|
||||
+ latval = -latval;
|
||||
+ }
|
||||
+ else
|
||||
+ northsouth = 'N';
|
||||
+
|
||||
+ latsecfrac = latval % 1000;
|
||||
+ latval = latval / 1000;
|
||||
+ latsec = latval % 60;
|
||||
+ latval = latval / 60;
|
||||
+ latmin = latval % 60;
|
||||
+ latval = latval / 60;
|
||||
+ latdeg = latval;
|
||||
+
|
||||
+ if (longval < 0) {
|
||||
+ eastwest = 'W';
|
||||
+ longval = -longval;
|
||||
+ }
|
||||
+ else
|
||||
+ eastwest = 'E';
|
||||
+
|
||||
+ longsecfrac = longval % 1000;
|
||||
+ longval = longval / 1000;
|
||||
+ longsec = longval % 60;
|
||||
+ longval = longval / 60;
|
||||
+ longmin = longval % 60;
|
||||
+ longval = longval / 60;
|
||||
+ longdeg = longval;
|
||||
+
|
||||
+ altfrac = altval % 100;
|
||||
+ altmeters = (altval / 100) * altsign;
|
||||
+
|
||||
+ sizestr = strdup(precsize_ntoa(sizeval));
|
||||
+ hpstr = strdup(precsize_ntoa(hpval));
|
||||
+ vpstr = strdup(precsize_ntoa(vpval));
|
||||
+
|
||||
+ sprintf(cp,
|
||||
+ "%d %.2d %.2d.%.3d %c %d %.2d %.2d.%.3d %c %d.%.2dm %sm %sm %sm",
|
||||
+ latdeg, latmin, latsec, latsecfrac, northsouth,
|
||||
+ longdeg, longmin, longsec, longsecfrac, eastwest,
|
||||
+ altmeters, altfrac, sizestr, hpstr, vpstr);
|
||||
+ free(sizestr);
|
||||
+ free(hpstr);
|
||||
+ free(vpstr);
|
||||
+
|
||||
+ return (cp);
|
||||
+}
|
||||
20
contrib/lease-access/README
Normal file
20
contrib/lease-access/README
Normal file
@@ -0,0 +1,20 @@
|
||||
Hello,
|
||||
|
||||
For some specific application I needed to deny access to a MAC address
|
||||
to a lease. For this reason I modified the dhcp-script behavior and is
|
||||
called with an extra parameter "access" once a dhcp request or discover
|
||||
is received. In that case if the exit code of the script is zero,
|
||||
dnsmasq continues normally, and if non-zero the packet is ignored.
|
||||
|
||||
This was not added as a security feature but as a mean to handle
|
||||
differently some addresses. It is also quite intrusive since it requires
|
||||
changes in several other subsystems.
|
||||
|
||||
It attach the patch in case someone is interested.
|
||||
|
||||
regards,
|
||||
Nikos
|
||||
|
||||
nmav@gennetsa.com
|
||||
|
||||
|
||||
578
contrib/lease-access/lease.access.patch
Normal file
578
contrib/lease-access/lease.access.patch
Normal file
@@ -0,0 +1,578 @@
|
||||
Index: src/dnsmasq.c
|
||||
===================================================================
|
||||
--- src/dnsmasq.c (revision 696)
|
||||
+++ src/dnsmasq.c (revision 821)
|
||||
@@ -59,7 +59,6 @@
|
||||
static int set_dns_listeners(time_t now, fd_set *set, int *maxfdp);
|
||||
static void check_dns_listeners(fd_set *set, time_t now);
|
||||
static void sig_handler(int sig);
|
||||
-static void async_event(int pipe, time_t now);
|
||||
static void fatal_event(struct event_desc *ev);
|
||||
static void poll_resolv(void);
|
||||
|
||||
@@ -275,7 +274,7 @@
|
||||
piperead = pipefd[0];
|
||||
pipewrite = pipefd[1];
|
||||
/* prime the pipe to load stuff first time. */
|
||||
- send_event(pipewrite, EVENT_RELOAD, 0);
|
||||
+ send_event(pipewrite, EVENT_RELOAD, 0, 0);
|
||||
|
||||
err_pipe[1] = -1;
|
||||
|
||||
@@ -340,7 +339,7 @@
|
||||
}
|
||||
else if (getuid() == 0)
|
||||
{
|
||||
- send_event(err_pipe[1], EVENT_PIDFILE, errno);
|
||||
+ send_event(err_pipe[1], EVENT_PIDFILE, errno, 0);
|
||||
_exit(0);
|
||||
}
|
||||
}
|
||||
@@ -372,7 +371,7 @@
|
||||
(setgroups(0, &dummy) == -1 ||
|
||||
setgid(gp->gr_gid) == -1))
|
||||
{
|
||||
- send_event(err_pipe[1], EVENT_GROUP_ERR, errno);
|
||||
+ send_event(err_pipe[1], EVENT_GROUP_ERR, errno, 0);
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
@@ -415,14 +414,14 @@
|
||||
|
||||
if (bad_capabilities != 0)
|
||||
{
|
||||
- send_event(err_pipe[1], EVENT_CAP_ERR, bad_capabilities);
|
||||
+ send_event(err_pipe[1], EVENT_CAP_ERR, bad_capabilities, 0);
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
/* finally drop root */
|
||||
if (setuid(ent_pw->pw_uid) == -1)
|
||||
{
|
||||
- send_event(err_pipe[1], EVENT_USER_ERR, errno);
|
||||
+ send_event(err_pipe[1], EVENT_USER_ERR, errno, 0);
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
@@ -434,7 +433,7 @@
|
||||
/* lose the setuid and setgid capabilities */
|
||||
if (capset(hdr, data) == -1)
|
||||
{
|
||||
- send_event(err_pipe[1], EVENT_CAP_ERR, errno);
|
||||
+ send_event(err_pipe[1], EVENT_CAP_ERR, errno, 0);
|
||||
_exit(0);
|
||||
}
|
||||
#endif
|
||||
@@ -647,7 +646,7 @@
|
||||
}
|
||||
|
||||
if (FD_ISSET(piperead, &rset))
|
||||
- async_event(piperead, now);
|
||||
+ async_event(piperead, now, NULL, 0);
|
||||
|
||||
#ifdef HAVE_LINUX_NETWORK
|
||||
if (FD_ISSET(daemon->netlinkfd, &rset))
|
||||
@@ -674,7 +673,7 @@
|
||||
#endif
|
||||
|
||||
if (daemon->dhcp && FD_ISSET(daemon->dhcpfd, &rset))
|
||||
- dhcp_packet(now);
|
||||
+ dhcp_packet(piperead, now);
|
||||
|
||||
#ifndef NO_FORK
|
||||
if (daemon->helperfd != -1 && FD_ISSET(daemon->helperfd, &wset))
|
||||
@@ -719,17 +718,18 @@
|
||||
else
|
||||
return;
|
||||
|
||||
- send_event(pipewrite, event, 0);
|
||||
+ send_event(pipewrite, event, 0, 0);
|
||||
errno = errsave;
|
||||
}
|
||||
}
|
||||
|
||||
-void send_event(int fd, int event, int data)
|
||||
+void send_event(int fd, int event, int data, int priv)
|
||||
{
|
||||
struct event_desc ev;
|
||||
|
||||
ev.event = event;
|
||||
ev.data = data;
|
||||
+ ev.priv = priv;
|
||||
|
||||
/* error pipe, debug mode. */
|
||||
if (fd == -1)
|
||||
@@ -771,14 +771,17 @@
|
||||
die(_("cannot open %s: %s"), daemon->log_file ? daemon->log_file : "log", EC_FILE);
|
||||
}
|
||||
}
|
||||
-
|
||||
-static void async_event(int pipe, time_t now)
|
||||
+
|
||||
+/* returns the private data of the event
|
||||
+ */
|
||||
+int async_event(int pipe, time_t now, struct event_desc* event, unsigned int secs)
|
||||
{
|
||||
pid_t p;
|
||||
struct event_desc ev;
|
||||
int i;
|
||||
|
||||
- if (read_write(pipe, (unsigned char *)&ev, sizeof(ev), 1))
|
||||
+ if (read_timeout(pipe, (unsigned char *)&ev, sizeof(ev), now, secs) > 0)
|
||||
+ {
|
||||
switch (ev.event)
|
||||
{
|
||||
case EVENT_RELOAD:
|
||||
@@ -872,6 +875,14 @@
|
||||
flush_log();
|
||||
exit(EC_GOOD);
|
||||
}
|
||||
+ }
|
||||
+ else
|
||||
+ return -1; /* timeout */
|
||||
+
|
||||
+ if (event)
|
||||
+ memcpy( event, &ev, sizeof(ev));
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static void poll_resolv()
|
||||
Index: src/config.h
|
||||
===================================================================
|
||||
--- src/config.h (revision 696)
|
||||
+++ src/config.h (revision 821)
|
||||
@@ -51,6 +51,8 @@
|
||||
#define TFTP_MAX_CONNECTIONS 50 /* max simultaneous connections */
|
||||
#define LOG_MAX 5 /* log-queue length */
|
||||
#define RANDFILE "/dev/urandom"
|
||||
+#define SCRIPT_TIMEOUT 6
|
||||
+#define LEASE_CHECK_TIMEOUT 10
|
||||
|
||||
/* DBUS interface specifics */
|
||||
#define DNSMASQ_SERVICE "uk.org.thekelleys.dnsmasq"
|
||||
Index: src/dnsmasq.h
|
||||
===================================================================
|
||||
--- src/dnsmasq.h (revision 696)
|
||||
+++ src/dnsmasq.h (revision 821)
|
||||
@@ -116,6 +116,7 @@
|
||||
/* Async event queue */
|
||||
struct event_desc {
|
||||
int event, data;
|
||||
+ unsigned int priv;
|
||||
};
|
||||
|
||||
#define EVENT_RELOAD 1
|
||||
@@ -390,6 +391,7 @@
|
||||
#define ACTION_OLD_HOSTNAME 2
|
||||
#define ACTION_OLD 3
|
||||
#define ACTION_ADD 4
|
||||
+#define ACTION_ACCESS 5
|
||||
|
||||
#define DHCP_CHADDR_MAX 16
|
||||
|
||||
@@ -709,6 +711,7 @@
|
||||
char *print_mac(char *buff, unsigned char *mac, int len);
|
||||
void bump_maxfd(int fd, int *max);
|
||||
int read_write(int fd, unsigned char *packet, int size, int rw);
|
||||
+int read_timeout(int fd, unsigned char *packet, int size, time_t now, int secs);
|
||||
|
||||
/* log.c */
|
||||
void die(char *message, char *arg1, int exit_code);
|
||||
@@ -748,7 +751,7 @@
|
||||
|
||||
/* dhcp.c */
|
||||
void dhcp_init(void);
|
||||
-void dhcp_packet(time_t now);
|
||||
+void dhcp_packet(int piperead, time_t now);
|
||||
|
||||
struct dhcp_context *address_available(struct dhcp_context *context,
|
||||
struct in_addr addr,
|
||||
@@ -792,14 +795,16 @@
|
||||
void rerun_scripts(void);
|
||||
|
||||
/* rfc2131.c */
|
||||
-size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
|
||||
+size_t dhcp_reply(int pipefd, struct dhcp_context *context, char *iface_name, int int_index,
|
||||
size_t sz, time_t now, int unicast_dest, int *is_inform);
|
||||
|
||||
/* dnsmasq.c */
|
||||
int make_icmp_sock(void);
|
||||
int icmp_ping(struct in_addr addr);
|
||||
-void send_event(int fd, int event, int data);
|
||||
+void send_event(int fd, int event, int data, int priv);
|
||||
void clear_cache_and_reload(time_t now);
|
||||
+int wait_for_child(int pipe);
|
||||
+int async_event(int pipe, time_t now, struct event_desc*, unsigned int timeout);
|
||||
|
||||
/* isc.c */
|
||||
#ifdef HAVE_ISC_READER
|
||||
@@ -832,9 +837,9 @@
|
||||
/* helper.c */
|
||||
#ifndef NO_FORK
|
||||
int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd);
|
||||
-void helper_write(void);
|
||||
+int helper_write(void);
|
||||
void queue_script(int action, struct dhcp_lease *lease,
|
||||
- char *hostname, time_t now);
|
||||
+ char *hostname, time_t now, unsigned int uid);
|
||||
int helper_buf_empty(void);
|
||||
#endif
|
||||
|
||||
Index: src/util.c
|
||||
===================================================================
|
||||
--- src/util.c (revision 696)
|
||||
+++ src/util.c (revision 821)
|
||||
@@ -444,3 +444,38 @@
|
||||
return 1;
|
||||
}
|
||||
|
||||
+int read_timeout(int fd, unsigned char *packet, int size, time_t now, int secs)
|
||||
+{
|
||||
+ ssize_t n, done;
|
||||
+ time_t expire;
|
||||
+
|
||||
+ expire = now + secs;
|
||||
+
|
||||
+ for (done = 0; done < size; done += n)
|
||||
+ {
|
||||
+ retry:
|
||||
+ if (secs > 0) alarm(secs);
|
||||
+ n = read(fd, &packet[done], (size_t)(size - done));
|
||||
+
|
||||
+ if (n == 0)
|
||||
+ return 0;
|
||||
+ else if (n == -1)
|
||||
+ {
|
||||
+ if (errno == EINTR) {
|
||||
+ my_syslog(LOG_INFO, _("read timed out (errno %d)"), errno);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if (retry_send() || errno == ENOMEM || errno == ENOBUFS || errno == EAGAIN)
|
||||
+ {
|
||||
+ if (secs == 0 || (secs > 0 && dnsmasq_time() < expire))
|
||||
+ goto retry;
|
||||
+ }
|
||||
+
|
||||
+ my_syslog(LOG_INFO, _("error in read (timeout %d, errno %d)"), secs, errno);
|
||||
+ return 0;
|
||||
+ }
|
||||
+ }
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
Index: src/dhcp.c
|
||||
===================================================================
|
||||
--- src/dhcp.c (revision 696)
|
||||
+++ src/dhcp.c (revision 821)
|
||||
@@ -103,7 +103,7 @@
|
||||
daemon->dhcp_packet.iov_base = safe_malloc(daemon->dhcp_packet.iov_len);
|
||||
}
|
||||
|
||||
-void dhcp_packet(time_t now)
|
||||
+void dhcp_packet(int piperead, time_t now)
|
||||
{
|
||||
struct dhcp_packet *mess;
|
||||
struct dhcp_context *context;
|
||||
@@ -239,7 +239,8 @@
|
||||
if (!iface_enumerate(&parm, complete_context, NULL))
|
||||
return;
|
||||
lease_prune(NULL, now); /* lose any expired leases */
|
||||
- iov.iov_len = dhcp_reply(parm.current, ifr.ifr_name, iface_index, (size_t)sz,
|
||||
+
|
||||
+ iov.iov_len = dhcp_reply(piperead, parm.current, ifr.ifr_name, iface_index, (size_t)sz,
|
||||
now, unicast_dest, &is_inform);
|
||||
lease_update_file(now);
|
||||
lease_update_dns();
|
||||
Index: src/helper.c
|
||||
===================================================================
|
||||
--- src/helper.c (revision 696)
|
||||
+++ src/helper.c (revision 821)
|
||||
@@ -45,6 +45,7 @@
|
||||
#endif
|
||||
unsigned char hwaddr[DHCP_CHADDR_MAX];
|
||||
char interface[IF_NAMESIZE];
|
||||
+ unsigned int uid;
|
||||
};
|
||||
|
||||
static struct script_data *buf = NULL;
|
||||
@@ -60,7 +61,7 @@
|
||||
then fork our process. */
|
||||
if (pipe(pipefd) == -1 || !fix_fd(pipefd[1]) || (pid = fork()) == -1)
|
||||
{
|
||||
- send_event(err_fd, EVENT_PIPE_ERR, errno);
|
||||
+ send_event(err_fd, EVENT_PIPE_ERR, errno, 0);
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
@@ -87,13 +88,13 @@
|
||||
{
|
||||
if (daemon->options & OPT_NO_FORK)
|
||||
/* send error to daemon process if no-fork */
|
||||
- send_event(event_fd, EVENT_HUSER_ERR, errno);
|
||||
+ send_event(event_fd, EVENT_HUSER_ERR, errno, 0);
|
||||
else
|
||||
{
|
||||
/* kill daemon */
|
||||
- send_event(event_fd, EVENT_DIE, 0);
|
||||
+ send_event(event_fd, EVENT_DIE, 0, 0);
|
||||
/* return error */
|
||||
- send_event(err_fd, EVENT_HUSER_ERR, errno);;
|
||||
+ send_event(err_fd, EVENT_HUSER_ERR, errno, 0);
|
||||
}
|
||||
_exit(0);
|
||||
}
|
||||
@@ -122,6 +123,8 @@
|
||||
action_str = "del";
|
||||
else if (data.action == ACTION_ADD)
|
||||
action_str = "add";
|
||||
+ else if (data.action == ACTION_ACCESS)
|
||||
+ action_str = "access";
|
||||
else if (data.action == ACTION_OLD || data.action == ACTION_OLD_HOSTNAME)
|
||||
action_str = "old";
|
||||
else
|
||||
@@ -178,9 +181,11 @@
|
||||
{
|
||||
/* On error send event back to main process for logging */
|
||||
if (WIFSIGNALED(status))
|
||||
- send_event(event_fd, EVENT_KILLED, WTERMSIG(status));
|
||||
- else if (WIFEXITED(status) && WEXITSTATUS(status) != 0)
|
||||
- send_event(event_fd, EVENT_EXITED, WEXITSTATUS(status));
|
||||
+ send_event(event_fd, EVENT_KILLED, WTERMSIG(status), data.uid);
|
||||
+ else if (WIFEXITED(status))
|
||||
+ send_event(event_fd, EVENT_EXITED, WEXITSTATUS(status), data.uid);
|
||||
+ else
|
||||
+ send_event(event_fd, EVENT_EXITED, -1, data.uid);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -263,7 +268,7 @@
|
||||
err = errno;
|
||||
}
|
||||
/* failed, send event so the main process logs the problem */
|
||||
- send_event(event_fd, EVENT_EXEC_ERR, err);
|
||||
+ send_event(event_fd, EVENT_EXEC_ERR, err, data.uid);
|
||||
_exit(0);
|
||||
}
|
||||
}
|
||||
@@ -295,7 +300,7 @@
|
||||
}
|
||||
|
||||
/* pack up lease data into a buffer */
|
||||
-void queue_script(int action, struct dhcp_lease *lease, char *hostname, time_t now)
|
||||
+void queue_script(int action, struct dhcp_lease *lease, char *hostname, time_t now, unsigned int uid)
|
||||
{
|
||||
unsigned char *p;
|
||||
size_t size;
|
||||
@@ -332,6 +337,7 @@
|
||||
buf_size = size;
|
||||
}
|
||||
|
||||
+ buf->uid = uid;
|
||||
buf->action = action;
|
||||
buf->hwaddr_len = lease->hwaddr_len;
|
||||
buf->hwaddr_type = lease->hwaddr_type;
|
||||
@@ -393,12 +399,15 @@
|
||||
return bytes_in_buf == 0;
|
||||
}
|
||||
|
||||
-void helper_write(void)
|
||||
+/* returns -1 if write failed for a reason, 1 if no data exist
|
||||
+ * and 0 if everything was ok.
|
||||
+ */
|
||||
+int helper_write(void)
|
||||
{
|
||||
ssize_t rc;
|
||||
|
||||
if (bytes_in_buf == 0)
|
||||
- return;
|
||||
+ return 1;
|
||||
|
||||
if ((rc = write(daemon->helperfd, buf, bytes_in_buf)) != -1)
|
||||
{
|
||||
@@ -409,9 +418,11 @@
|
||||
else
|
||||
{
|
||||
if (errno == EAGAIN || errno == EINTR)
|
||||
- return;
|
||||
+ return -1;
|
||||
bytes_in_buf = 0;
|
||||
}
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
Index: src/rfc2131.c
|
||||
===================================================================
|
||||
--- src/rfc2131.c (revision 696)
|
||||
+++ src/rfc2131.c (revision 821)
|
||||
@@ -100,8 +100,49 @@
|
||||
int clid_len, unsigned char *clid, int *len_out);
|
||||
static void match_vendor_opts(unsigned char *opt, struct dhcp_opt *dopt);
|
||||
|
||||
+static int check_access_script( int piperead, struct dhcp_lease *lease, struct dhcp_packet *mess, time_t now)
|
||||
+{
|
||||
+#ifndef NO_FORK
|
||||
+unsigned int uid;
|
||||
+struct event_desc ev;
|
||||
+int ret;
|
||||
+struct dhcp_lease _lease;
|
||||
+
|
||||
+ if (daemon->lease_change_command == NULL) return 0; /* ok */
|
||||
+
|
||||
+ if (!lease) { /* if host has not been seen before lease is NULL */
|
||||
+ memset(&_lease, 0, sizeof(_lease));
|
||||
+ lease = &_lease;
|
||||
+ lease_set_hwaddr(lease, mess->chaddr, NULL, mess->hlen, mess->htype, 0);
|
||||
+ }
|
||||
+
|
||||
+ uid = rand16();
|
||||
+ queue_script(ACTION_ACCESS, lease, NULL, now, uid);
|
||||
+
|
||||
+ /* send all data to helper process */
|
||||
+ do
|
||||
+ {
|
||||
+ helper_write();
|
||||
+ } while (helper_buf_empty() == 0);
|
||||
+
|
||||
+ /* wait for our event */
|
||||
+ ret = 0;
|
||||
+ do
|
||||
+ {
|
||||
+ ret = async_event( piperead, now, &ev, SCRIPT_TIMEOUT);
|
||||
+ }
|
||||
+ while(ev.priv != uid && ret >= 0);
|
||||
+
|
||||
+ if (ret < 0 || ev.data != 0) /* timeout or error */
|
||||
+ {
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+#endif
|
||||
+ return 0; /* ok */
|
||||
+}
|
||||
|
||||
-size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
|
||||
+size_t dhcp_reply(int piperead, struct dhcp_context *context, char *iface_name, int int_index,
|
||||
size_t sz, time_t now, int unicast_dest, int *is_inform)
|
||||
{
|
||||
unsigned char *opt, *clid = NULL;
|
||||
@@ -252,7 +293,7 @@
|
||||
mac->netid.next = netid;
|
||||
netid = &mac->netid;
|
||||
}
|
||||
-
|
||||
+
|
||||
/* Determine network for this packet. Our caller will have already linked all the
|
||||
contexts which match the addresses of the receiving interface but if the
|
||||
machine has an address already, or came via a relay, or we have a subnet selector,
|
||||
@@ -329,7 +370,7 @@
|
||||
my_syslog(LOG_INFO, _("Available DHCP range: %s -- %s"), daemon->namebuff, inet_ntoa(context_tmp->end));
|
||||
}
|
||||
}
|
||||
-
|
||||
+
|
||||
mess->op = BOOTREPLY;
|
||||
|
||||
config = find_config(daemon->dhcp_conf, context, clid, clid_len,
|
||||
@@ -418,7 +459,7 @@
|
||||
else
|
||||
mess->yiaddr = lease->addr;
|
||||
}
|
||||
-
|
||||
+
|
||||
if (!message &&
|
||||
!lease &&
|
||||
(!(lease = lease_allocate(mess->yiaddr))))
|
||||
@@ -641,7 +682,14 @@
|
||||
memcpy(req_options, option_ptr(opt, 0), option_len(opt));
|
||||
req_options[option_len(opt)] = OPTION_END;
|
||||
}
|
||||
-
|
||||
+
|
||||
+ if (mess_type == DHCPREQUEST || mess_type == DHCPDISCOVER)
|
||||
+ if (check_access_script(piperead, lease, mess, now) < 0)
|
||||
+ {
|
||||
+ my_syslog(LOG_INFO, _("Ignoring client due to access script"));
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
switch (mess_type)
|
||||
{
|
||||
case DHCPDECLINE:
|
||||
Index: src/log.c
|
||||
===================================================================
|
||||
--- src/log.c (revision 696)
|
||||
+++ src/log.c (revision 821)
|
||||
@@ -73,7 +73,7 @@
|
||||
|
||||
if (!log_reopen(daemon->log_file))
|
||||
{
|
||||
- send_event(errfd, EVENT_LOG_ERR, errno);
|
||||
+ send_event(errfd, EVENT_LOG_ERR, errno, 0);
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
Index: src/lease.c
|
||||
===================================================================
|
||||
--- src/lease.c (revision 696)
|
||||
+++ src/lease.c (revision 821)
|
||||
@@ -511,7 +511,7 @@
|
||||
if (lease->old_hostname)
|
||||
{
|
||||
#ifndef NO_FORK
|
||||
- queue_script(ACTION_OLD_HOSTNAME, lease, lease->old_hostname, now);
|
||||
+ queue_script(ACTION_OLD_HOSTNAME, lease, lease->old_hostname, now, 0);
|
||||
#endif
|
||||
free(lease->old_hostname);
|
||||
lease->old_hostname = NULL;
|
||||
@@ -520,7 +520,7 @@
|
||||
else
|
||||
{
|
||||
#ifndef NO_FORK
|
||||
- queue_script(ACTION_DEL, lease, lease->hostname, now);
|
||||
+ queue_script(ACTION_DEL, lease, lease->hostname, now, 0);
|
||||
#endif
|
||||
old_leases = lease->next;
|
||||
|
||||
@@ -540,7 +540,7 @@
|
||||
if (lease->old_hostname)
|
||||
{
|
||||
#ifndef NO_FORK
|
||||
- queue_script(ACTION_OLD_HOSTNAME, lease, lease->old_hostname, now);
|
||||
+ queue_script(ACTION_OLD_HOSTNAME, lease, lease->old_hostname, now, 0);
|
||||
#endif
|
||||
free(lease->old_hostname);
|
||||
lease->old_hostname = NULL;
|
||||
@@ -552,7 +552,7 @@
|
||||
(lease->aux_changed && (daemon->options & OPT_LEASE_RO)))
|
||||
{
|
||||
#ifndef NO_FORK
|
||||
- queue_script(lease->new ? ACTION_ADD : ACTION_OLD, lease, lease->hostname, now);
|
||||
+ queue_script(lease->new ? ACTION_ADD : ACTION_OLD, lease, lease->hostname, now, 0);
|
||||
#endif
|
||||
lease->new = lease->changed = lease->aux_changed = 0;
|
||||
|
||||
Index: man/dnsmasq.8
|
||||
===================================================================
|
||||
--- man/dnsmasq.8 (revision 696)
|
||||
+++ man/dnsmasq.8 (revision 821)
|
||||
@@ -724,12 +724,15 @@
|
||||
.B \-6 --dhcp-script=<path>
|
||||
Whenever a new DHCP lease is created, or an old one destroyed, the
|
||||
binary specified by this option is run. The arguments to the process
|
||||
-are "add", "old" or "del", the MAC
|
||||
+are "add", "old", "access" or "del", the MAC
|
||||
address of the host (or "<null>"), the IP address, and the hostname,
|
||||
if known. "add" means a lease has been created, "del" means it has
|
||||
been destroyed, "old" is a notification of an existing lease when
|
||||
dnsmasq starts or a change to MAC address or hostname of an existing
|
||||
lease (also, lease length or expiry and client-id, if leasefile-ro is set).
|
||||
+The "access" keyword means that a request was just received and depending
|
||||
+on the script exit status request for address will be granted, if exit status
|
||||
+is zero or not if it is non-zero.
|
||||
The process is run as root (assuming that dnsmasq was originally run as
|
||||
root) even if dnsmasq is configured to change UID to an unprivileged user.
|
||||
The environment is inherited from the invoker of dnsmasq, and if the
|
||||
6
contrib/lease-tools/Makefile
Normal file
6
contrib/lease-tools/Makefile
Normal file
@@ -0,0 +1,6 @@
|
||||
CFLAGS?= -O2 -Wall -W
|
||||
|
||||
all: dhcp_release dhcp_release6 dhcp_lease_time
|
||||
|
||||
clean:
|
||||
rm -f *~ *.o core dhcp_release dhcp_release6 dhcp_lease_time
|
||||
25
contrib/lease-tools/dhcp_lease_time.1
Normal file
25
contrib/lease-tools/dhcp_lease_time.1
Normal file
@@ -0,0 +1,25 @@
|
||||
.TH DHCP_LEASE_TIME 1
|
||||
.SH NAME
|
||||
dhcp_lease_time \- Query remaining time of a lease on a the local dnsmasq DHCP server.
|
||||
.SH SYNOPSIS
|
||||
.B dhcp_lease_time <address>
|
||||
.SH "DESCRIPTION"
|
||||
Send a DHCPINFORM message to a dnsmasq server running on the local host
|
||||
and print (to stdout) the time remaining in any lease for the given
|
||||
address. The time is given as string printed to stdout.
|
||||
|
||||
If an error occurs or no lease exists for the given address,
|
||||
nothing is sent to stdout a message is sent to stderr and a
|
||||
non-zero error code is returned.
|
||||
|
||||
Requires dnsmasq 2.67 or later and may not work with other DHCP servers.
|
||||
|
||||
The address argument is a dotted-quad IP addresses and mandatory.
|
||||
.SH LIMITATIONS
|
||||
Only works with IPv4 addresses and DHCP leases.
|
||||
.SH SEE ALSO
|
||||
.BR dnsmasq (8)
|
||||
.SH AUTHOR
|
||||
This manual page was written by Simon Kelley <simon@thekelleys.org.uk>.
|
||||
|
||||
|
||||
225
contrib/lease-tools/dhcp_lease_time.c
Normal file
225
contrib/lease-tools/dhcp_lease_time.c
Normal file
@@ -0,0 +1,225 @@
|
||||
/* Copyright (c) 2007 Simon Kelley
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 dated June, 1991.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
/* dhcp_lease_time <address> */
|
||||
|
||||
/* Send a DHCPINFORM message to a dnsmasq server running on the local host
|
||||
and print (to stdout) the time remaining in any lease for the given
|
||||
address. The time is given as string printed to stdout.
|
||||
|
||||
If an error occurs or no lease exists for the given address,
|
||||
nothing is sent to stdout a message is sent to stderr and a
|
||||
non-zero error code is returned.
|
||||
|
||||
This version requires dnsmasq 2.67 or later.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <net/if.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <net/if_arp.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/netlink.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define DHCP_CHADDR_MAX 16
|
||||
#define BOOTREQUEST 1
|
||||
#define DHCP_COOKIE 0x63825363
|
||||
#define OPTION_PAD 0
|
||||
#define OPTION_LEASE_TIME 51
|
||||
#define OPTION_OVERLOAD 52
|
||||
#define OPTION_MESSAGE_TYPE 53
|
||||
#define OPTION_REQUESTED_OPTIONS 55
|
||||
#define OPTION_END 255
|
||||
#define DHCPINFORM 8
|
||||
#define DHCP_SERVER_PORT 67
|
||||
|
||||
#define option_len(opt) ((int)(((unsigned char *)(opt))[1]))
|
||||
#define option_ptr(opt) ((void *)&(((unsigned char *)(opt))[2]))
|
||||
|
||||
|
||||
typedef unsigned char u8;
|
||||
typedef unsigned short u16;
|
||||
typedef unsigned int u32;
|
||||
|
||||
struct dhcp_packet {
|
||||
u8 op, htype, hlen, hops;
|
||||
u32 xid;
|
||||
u16 secs, flags;
|
||||
struct in_addr ciaddr, yiaddr, siaddr, giaddr;
|
||||
u8 chaddr[DHCP_CHADDR_MAX], sname[64], file[128];
|
||||
u32 cookie;
|
||||
unsigned char options[308];
|
||||
};
|
||||
|
||||
static unsigned char *option_find1(unsigned char *p, unsigned char *end, int opt, int minsize)
|
||||
{
|
||||
while (*p != OPTION_END)
|
||||
{
|
||||
if (p >= end)
|
||||
return NULL; /* malformed packet */
|
||||
else if (*p == OPTION_PAD)
|
||||
p++;
|
||||
else
|
||||
{
|
||||
int opt_len;
|
||||
if (p >= end - 2)
|
||||
return NULL; /* malformed packet */
|
||||
opt_len = option_len(p);
|
||||
if (end - p < (2 + opt_len))
|
||||
return NULL; /* malformed packet */
|
||||
if (*p == opt && opt_len >= minsize)
|
||||
return p;
|
||||
p += opt_len + 2;
|
||||
}
|
||||
}
|
||||
|
||||
return opt == OPTION_END ? p : NULL;
|
||||
}
|
||||
|
||||
static unsigned char *option_find(struct dhcp_packet *mess, size_t size, int opt_type, int minsize)
|
||||
{
|
||||
unsigned char *ret, *overload;
|
||||
|
||||
/* skip over DHCP cookie; */
|
||||
if ((ret = option_find1(&mess->options[0], ((unsigned char *)mess) + size, opt_type, minsize)))
|
||||
return ret;
|
||||
|
||||
/* look for overload option. */
|
||||
if (!(overload = option_find1(&mess->options[0], ((unsigned char *)mess) + size, OPTION_OVERLOAD, 1)))
|
||||
return NULL;
|
||||
|
||||
/* Can we look in filename area ? */
|
||||
if ((overload[2] & 1) &&
|
||||
(ret = option_find1(&mess->file[0], &mess->file[128], opt_type, minsize)))
|
||||
return ret;
|
||||
|
||||
/* finally try sname area */
|
||||
if ((overload[2] & 2) &&
|
||||
(ret = option_find1(&mess->sname[0], &mess->sname[64], opt_type, minsize)))
|
||||
return ret;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static unsigned int option_uint(unsigned char *opt, int size)
|
||||
{
|
||||
/* this worries about unaligned data and byte order */
|
||||
unsigned int ret = 0;
|
||||
int i;
|
||||
unsigned char *p = option_ptr(opt);
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
ret = (ret << 8) | *p++;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct in_addr lease;
|
||||
struct dhcp_packet packet;
|
||||
unsigned char *p = packet.options;
|
||||
struct sockaddr_in dest;
|
||||
int fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
ssize_t rc;
|
||||
|
||||
if (argc < 2)
|
||||
{
|
||||
fprintf(stderr, "usage: dhcp_lease_time <address>\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (fd == -1)
|
||||
{
|
||||
perror("cannot create socket");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (inet_pton(AF_INET, argv[1], &lease) < 1)
|
||||
{
|
||||
fprintf(stderr, "invalid address: %s\n", argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(&packet, 0, sizeof(packet));
|
||||
|
||||
packet.hlen = 0;
|
||||
packet.htype = 0;
|
||||
|
||||
packet.op = BOOTREQUEST;
|
||||
packet.ciaddr = lease;
|
||||
packet.cookie = htonl(DHCP_COOKIE);
|
||||
|
||||
*(p++) = OPTION_MESSAGE_TYPE;
|
||||
*(p++) = 1;
|
||||
*(p++) = DHCPINFORM;
|
||||
|
||||
/* Explicitly request the lease time, it won't be sent otherwise:
|
||||
this is a dnsmasq extension, not standard. */
|
||||
*(p++) = OPTION_REQUESTED_OPTIONS;
|
||||
*(p++) = 1;
|
||||
*(p++) = OPTION_LEASE_TIME;
|
||||
|
||||
*(p++) = OPTION_END;
|
||||
|
||||
dest.sin_family = AF_INET;
|
||||
(void)inet_pton(AF_INET, "127.0.0.1", &dest.sin_addr);
|
||||
dest.sin_port = ntohs(DHCP_SERVER_PORT);
|
||||
|
||||
if (sendto(fd, &packet, sizeof(packet), 0,
|
||||
(struct sockaddr *)&dest, sizeof(dest)) == -1)
|
||||
{
|
||||
perror("sendto failed");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
alarm(3); /* noddy timeout. */
|
||||
|
||||
rc = recv(fd, &packet, sizeof(packet), 0);
|
||||
|
||||
if (rc < (ssize_t)(sizeof(packet) - sizeof(packet.options)))
|
||||
{
|
||||
perror("recv failed");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ((p = option_find(&packet, (size_t)rc, OPTION_LEASE_TIME, 4)))
|
||||
{
|
||||
unsigned int t = option_uint(p, 4);
|
||||
if (t == 0xffffffff)
|
||||
printf("infinite");
|
||||
else
|
||||
{
|
||||
unsigned int x;
|
||||
if ((x = t/86400))
|
||||
printf("%ud", x);
|
||||
if ((x = (t/3600)%24))
|
||||
printf("%uh", x);
|
||||
if ((x = (t/60)%60))
|
||||
printf("%um", x);
|
||||
if ((x = t%60))
|
||||
printf("%us", x);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1; /* no lease */
|
||||
}
|
||||
37
contrib/lease-tools/dhcp_release.1
Normal file
37
contrib/lease-tools/dhcp_release.1
Normal file
@@ -0,0 +1,37 @@
|
||||
.TH DHCP_RELEASE 1
|
||||
.SH NAME
|
||||
dhcp_release \- Release a DHCP lease on a the local dnsmasq DHCP server.
|
||||
.SH SYNOPSIS
|
||||
.B dhcp_release <interface> <address> <MAC address> <client_id>
|
||||
.SH "DESCRIPTION"
|
||||
A utility which forces the DHCP server running on this machine to release a
|
||||
DHCP lease.
|
||||
.PP
|
||||
Send a DHCPRELEASE message via the specified interface to tell the
|
||||
local DHCP server to delete a particular lease.
|
||||
|
||||
The interface argument is the interface in which a DHCP
|
||||
request _would_ be received if it was coming from the client,
|
||||
rather than being faked up here.
|
||||
|
||||
The address argument is a dotted-quad IP addresses and mandatory.
|
||||
|
||||
The MAC address is colon separated hex, and is mandatory. It may be
|
||||
prefixed by an address-type byte followed by -, eg
|
||||
|
||||
10-11:22:33:44:55:66
|
||||
|
||||
but if the address-type byte is missing it is assumed to be 1, the type
|
||||
for ethernet. This encoding is the one used in dnsmasq lease files.
|
||||
|
||||
The client-id is optional. If it is "*" then it treated as being missing.
|
||||
.SH NOTES
|
||||
MUST be run as root - will fail otherwise.
|
||||
.SH LIMITATIONS
|
||||
Only usable on IPv4 DHCP leases.
|
||||
.SH SEE ALSO
|
||||
.BR dnsmasq (8)
|
||||
.SH AUTHOR
|
||||
This manual page was written by Simon Kelley <simon@thekelleys.org.uk>.
|
||||
|
||||
|
||||
343
contrib/lease-tools/dhcp_release.c
Normal file
343
contrib/lease-tools/dhcp_release.c
Normal file
@@ -0,0 +1,343 @@
|
||||
/* Copyright (c) 2006 Simon Kelley
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 dated June, 1991.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
/* dhcp_release <interface> <address> <MAC address> <client_id>
|
||||
MUST be run as root - will fail otherwise. */
|
||||
|
||||
/* Send a DHCPRELEASE message via the specified interface
|
||||
to tell the local DHCP server to delete a particular lease.
|
||||
|
||||
The interface argument is the interface in which a DHCP
|
||||
request _would_ be received if it was coming from the client,
|
||||
rather than being faked up here.
|
||||
|
||||
The address argument is a dotted-quad IP addresses and mandatory.
|
||||
|
||||
The MAC address is colon separated hex, and is mandatory. It may be
|
||||
prefixed by an address-type byte followed by -, eg
|
||||
|
||||
10-11:22:33:44:55:66
|
||||
|
||||
but if the address-type byte is missing it is assumed to be 1, the type
|
||||
for ethernet. This encoding is the one used in dnsmasq lease files.
|
||||
|
||||
The client-id is optional. If it is "*" then it treated as being missing.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <net/if.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <net/if_arp.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/netlink.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define DHCP_CHADDR_MAX 16
|
||||
#define BOOTREQUEST 1
|
||||
#define DHCP_COOKIE 0x63825363
|
||||
#define OPTION_SERVER_IDENTIFIER 54
|
||||
#define OPTION_CLIENT_ID 61
|
||||
#define OPTION_MESSAGE_TYPE 53
|
||||
#define OPTION_END 255
|
||||
#define DHCPRELEASE 7
|
||||
#define DHCP_SERVER_PORT 67
|
||||
|
||||
typedef unsigned char u8;
|
||||
typedef unsigned short u16;
|
||||
typedef unsigned int u32;
|
||||
|
||||
struct dhcp_packet {
|
||||
u8 op, htype, hlen, hops;
|
||||
u32 xid;
|
||||
u16 secs, flags;
|
||||
struct in_addr ciaddr, yiaddr, siaddr, giaddr;
|
||||
u8 chaddr[DHCP_CHADDR_MAX], sname[64], file[128];
|
||||
u32 cookie;
|
||||
unsigned char options[308];
|
||||
};
|
||||
|
||||
static struct iovec iov;
|
||||
|
||||
static int expand_buf(struct iovec *iov, size_t size)
|
||||
{
|
||||
void *new;
|
||||
|
||||
if (size <= iov->iov_len)
|
||||
return 1;
|
||||
|
||||
if (!(new = malloc(size)))
|
||||
{
|
||||
errno = ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (iov->iov_base)
|
||||
{
|
||||
memcpy(new, iov->iov_base, iov->iov_len);
|
||||
free(iov->iov_base);
|
||||
}
|
||||
|
||||
iov->iov_base = new;
|
||||
iov->iov_len = size;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static ssize_t netlink_recv(int fd)
|
||||
{
|
||||
struct msghdr msg;
|
||||
ssize_t rc;
|
||||
|
||||
msg.msg_control = NULL;
|
||||
msg.msg_controllen = 0;
|
||||
msg.msg_name = NULL;
|
||||
msg.msg_namelen = 0;
|
||||
msg.msg_iov = &iov;
|
||||
msg.msg_iovlen = 1;
|
||||
|
||||
while (1)
|
||||
{
|
||||
msg.msg_flags = 0;
|
||||
while ((rc = recvmsg(fd, &msg, MSG_PEEK)) == -1 && errno == EINTR);
|
||||
|
||||
/* 2.2.x doesn't support MSG_PEEK at all, returning EOPNOTSUPP, so we just grab a
|
||||
big buffer and pray in that case. */
|
||||
if (rc == -1 && errno == EOPNOTSUPP)
|
||||
{
|
||||
if (!expand_buf(&iov, 2000))
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (rc == -1 || !(msg.msg_flags & MSG_TRUNC))
|
||||
break;
|
||||
|
||||
if (!expand_buf(&iov, iov.iov_len + 100))
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* finally, read it for real */
|
||||
while ((rc = recvmsg(fd, &msg, 0)) == -1 && errno == EINTR);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int parse_hex(char *in, unsigned char *out, int maxlen, int *mac_type)
|
||||
{
|
||||
int i = 0;
|
||||
char *r;
|
||||
|
||||
if (mac_type)
|
||||
*mac_type = 0;
|
||||
|
||||
while (maxlen == -1 || i < maxlen)
|
||||
{
|
||||
for (r = in; *r != 0 && *r != ':' && *r != '-'; r++);
|
||||
if (*r == 0)
|
||||
maxlen = i;
|
||||
|
||||
if (r != in )
|
||||
{
|
||||
if (*r == '-' && i == 0 && mac_type)
|
||||
{
|
||||
*r = 0;
|
||||
*mac_type = strtol(in, NULL, 16);
|
||||
mac_type = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
*r = 0;
|
||||
out[i] = strtol(in, NULL, 16);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
in = r+1;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
static int is_same_net(struct in_addr a, struct in_addr b, struct in_addr mask)
|
||||
{
|
||||
return (a.s_addr & mask.s_addr) == (b.s_addr & mask.s_addr);
|
||||
}
|
||||
|
||||
static struct in_addr find_interface(struct in_addr client, int fd, unsigned int index, int ifrfd, struct ifreq *ifr)
|
||||
{
|
||||
struct sockaddr_nl addr;
|
||||
struct nlmsghdr *h;
|
||||
ssize_t len;
|
||||
|
||||
struct {
|
||||
struct nlmsghdr nlh;
|
||||
struct rtgenmsg g;
|
||||
} req;
|
||||
|
||||
addr.nl_family = AF_NETLINK;
|
||||
addr.nl_pad = 0;
|
||||
addr.nl_groups = 0;
|
||||
addr.nl_pid = 0; /* address to kernel */
|
||||
|
||||
req.nlh.nlmsg_len = sizeof(req);
|
||||
req.nlh.nlmsg_type = RTM_GETADDR;
|
||||
req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST | NLM_F_ACK;
|
||||
req.nlh.nlmsg_pid = 0;
|
||||
req.nlh.nlmsg_seq = 1;
|
||||
req.g.rtgen_family = AF_INET;
|
||||
|
||||
if (sendto(fd, (void *)&req, sizeof(req), 0,
|
||||
(struct sockaddr *)&addr, sizeof(addr)) == -1)
|
||||
{
|
||||
perror("sendto failed");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
if ((len = netlink_recv(fd)) == -1)
|
||||
{
|
||||
perror("netlink");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (h = (struct nlmsghdr *)iov.iov_base; NLMSG_OK(h, (size_t)len); h = NLMSG_NEXT(h, len))
|
||||
if (h->nlmsg_type == NLMSG_DONE)
|
||||
{
|
||||
/* No match found, return first address as src/dhcp.c code does */
|
||||
ifr->ifr_addr.sa_family = AF_INET;
|
||||
if (ioctl(ifrfd, SIOCGIFADDR, ifr) != -1)
|
||||
return ((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr;
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "error: local IPv4 address not found\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
else if (h->nlmsg_type == RTM_NEWADDR)
|
||||
{
|
||||
struct ifaddrmsg *ifa = NLMSG_DATA(h);
|
||||
struct rtattr *rta;
|
||||
unsigned int len1 = h->nlmsg_len - NLMSG_LENGTH(sizeof(*ifa));
|
||||
|
||||
if (ifa->ifa_index == index && ifa->ifa_family == AF_INET)
|
||||
{
|
||||
struct in_addr netmask, addr;
|
||||
|
||||
netmask.s_addr = htonl(0xffffffff << (32 - ifa->ifa_prefixlen));
|
||||
addr.s_addr = 0;
|
||||
|
||||
for (rta = IFA_RTA(ifa); RTA_OK(rta, len1); rta = RTA_NEXT(rta, len1))
|
||||
if (rta->rta_type == IFA_LOCAL)
|
||||
addr = *((struct in_addr *)(rta+1));
|
||||
|
||||
if (addr.s_addr && is_same_net(addr, client, netmask))
|
||||
return addr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct in_addr server, lease;
|
||||
int mac_type;
|
||||
struct dhcp_packet packet;
|
||||
unsigned char *p = packet.options;
|
||||
struct sockaddr_in dest;
|
||||
struct ifreq ifr;
|
||||
int fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
int nl = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
|
||||
|
||||
if (argc < 4 || argc > 5)
|
||||
{
|
||||
fprintf(stderr, "usage: dhcp_release <interface> <addr> <mac> [<client_id>]\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (fd == -1 || nl == -1)
|
||||
{
|
||||
perror("cannot create socket");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* This voodoo fakes up a packet coming from the correct interface, which really matters for
|
||||
a DHCP server */
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
strncpy(ifr.ifr_name, argv[1], sizeof(ifr.ifr_name)-1);
|
||||
ifr.ifr_name[sizeof(ifr.ifr_name)-1] = '\0';
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr)) == -1)
|
||||
{
|
||||
perror("cannot setup interface");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (inet_pton(AF_INET, argv[2], &lease.s_addr) < 1)
|
||||
{
|
||||
perror("invalid ip address");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
server = find_interface(lease, nl, if_nametoindex(argv[1]), fd, &ifr);
|
||||
|
||||
memset(&packet, 0, sizeof(packet));
|
||||
|
||||
packet.hlen = parse_hex(argv[3], packet.chaddr, DHCP_CHADDR_MAX, &mac_type);
|
||||
if (mac_type == 0)
|
||||
packet.htype = ARPHRD_ETHER;
|
||||
else
|
||||
packet.htype = mac_type;
|
||||
|
||||
packet.op = BOOTREQUEST;
|
||||
packet.ciaddr = lease;
|
||||
packet.cookie = htonl(DHCP_COOKIE);
|
||||
|
||||
*(p++) = OPTION_MESSAGE_TYPE;
|
||||
*(p++) = 1;
|
||||
*(p++) = DHCPRELEASE;
|
||||
|
||||
*(p++) = OPTION_SERVER_IDENTIFIER;
|
||||
*(p++) = sizeof(server);
|
||||
memcpy(p, &server, sizeof(server));
|
||||
p += sizeof(server);
|
||||
|
||||
if (argc == 5 && strcmp(argv[4], "*") != 0)
|
||||
{
|
||||
unsigned int clid_len = parse_hex(argv[4], p+2, 255, NULL);
|
||||
*(p++) = OPTION_CLIENT_ID;
|
||||
*(p++) = clid_len;
|
||||
p += clid_len;
|
||||
}
|
||||
|
||||
*(p++) = OPTION_END;
|
||||
|
||||
dest.sin_family = AF_INET;
|
||||
dest.sin_port = ntohs(DHCP_SERVER_PORT);
|
||||
dest.sin_addr = server;
|
||||
|
||||
if (sendto(fd, &packet, sizeof(packet), 0,
|
||||
(struct sockaddr *)&dest, sizeof(dest)) == -1)
|
||||
{
|
||||
perror("sendto failed");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
38
contrib/lease-tools/dhcp_release6.1
Normal file
38
contrib/lease-tools/dhcp_release6.1
Normal file
@@ -0,0 +1,38 @@
|
||||
.TH DHCP_RELEASE 1
|
||||
.SH NAME
|
||||
dhcp_release6 \- Release a DHCPv6 lease on a the local dnsmasq DHCP server.
|
||||
.SH SYNOPSIS
|
||||
.B dhcp_release6 --iface <interface> --client-id <client-id> --server-id
|
||||
server-id --iaid <iaid> --ip <IP> [--dry-run] [--help]
|
||||
.SH "DESCRIPTION"
|
||||
A utility which forces the DHCP server running on this machine to release a
|
||||
DHCPv6 lease.
|
||||
.SS OPTIONS
|
||||
.IP "-a, --ip"
|
||||
IPv6 address to release.
|
||||
.IP "-c, --client-id"
|
||||
Colon-separated hex string representing DHCPv6 client id. Normally
|
||||
it can be found in leases file both on client and server.
|
||||
.IP "-d, --dry-run"
|
||||
Print hexadecimal representation of generated DHCPv6 release packet to standard
|
||||
output and exit.
|
||||
.IP "-h, --help"
|
||||
print usage information to standard output and exit.
|
||||
.IP "-i, --iaid"
|
||||
Decimal representation of DHCPv6 IAID. Normally it can be found in leases file
|
||||
both on client and server.
|
||||
.IP "-n, --iface"
|
||||
Network interface to send a DHCPv6 release packet from.
|
||||
.IP "-s, --server-id"
|
||||
Colon-separated hex string representing DHCPv6 server id. Normally
|
||||
it can be found in leases file both on client and server.
|
||||
.SH NOTES
|
||||
MUST be run as root - will fail otherwise.
|
||||
.SH LIMITATIONS
|
||||
Only usable on IPv6 DHCP leases.
|
||||
.SH SEE ALSO
|
||||
.BR dnsmasq (8)
|
||||
.SH AUTHOR
|
||||
This manual page was written by Simon Kelley <simon@thekelleys.org.uk>.
|
||||
|
||||
|
||||
508
contrib/lease-tools/dhcp_release6.c
Normal file
508
contrib/lease-tools/dhcp_release6.c
Normal file
@@ -0,0 +1,508 @@
|
||||
/*
|
||||
dhcp_release6 --iface <interface> --client-id <client-id> --server-id
|
||||
server-id --iaid <iaid> --ip <IP> [--dry-run] [--help]
|
||||
MUST be run as root - will fail otherwise
|
||||
*/
|
||||
|
||||
/* Send a DHCPRELEASE message to IPv6 multicast address via the specified interface
|
||||
to tell the local DHCP server to delete a particular lease.
|
||||
|
||||
The interface argument is the interface in which a DHCP
|
||||
request _would_ be received if it was coming from the client,
|
||||
rather than being faked up here.
|
||||
|
||||
The client-id argument is colon-separated hex string and mandatory. Normally
|
||||
it can be found in leases file both on client and server
|
||||
|
||||
The server-id argument is colon-separated hex string and mandatory. Normally
|
||||
it can be found in leases file both on client and server.
|
||||
|
||||
The iaid argument is numeric string and mandatory. Normally
|
||||
it can be found in leases file both on client and server.
|
||||
|
||||
IP is an IPv6 address to release
|
||||
|
||||
If --dry-run is specified, dhcp_release6 just prints hexadecimal representation of
|
||||
packet to send to stdout and exits.
|
||||
|
||||
If --help is specified, dhcp_release6 print usage information to stdout and exits
|
||||
|
||||
|
||||
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <getopt.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define NOT_REPLY_CODE 115
|
||||
typedef unsigned char u8;
|
||||
typedef unsigned short u16;
|
||||
typedef unsigned int u32;
|
||||
|
||||
enum DHCP6_TYPES
|
||||
{
|
||||
SOLICIT = 1,
|
||||
ADVERTISE = 2,
|
||||
REQUEST = 3,
|
||||
CONFIRM = 4,
|
||||
RENEW = 5,
|
||||
REBIND = 6,
|
||||
REPLY = 7,
|
||||
RELEASE = 8,
|
||||
DECLINE = 9,
|
||||
RECONFIGURE = 10,
|
||||
INFORMATION_REQUEST = 11,
|
||||
RELAY_FORW = 12,
|
||||
RELAY_REPL = 13
|
||||
|
||||
};
|
||||
|
||||
enum DHCP6_OPTIONS
|
||||
{
|
||||
CLIENTID = 1,
|
||||
SERVERID = 2,
|
||||
IA_NA = 3,
|
||||
IA_TA = 4,
|
||||
IAADDR = 5,
|
||||
ORO = 6,
|
||||
PREFERENCE = 7,
|
||||
ELAPSED_TIME = 8,
|
||||
RELAY_MSG = 9,
|
||||
AUTH = 11,
|
||||
UNICAST = 12,
|
||||
STATUS_CODE = 13,
|
||||
RAPID_COMMIT = 14,
|
||||
USER_CLASS = 15,
|
||||
VENDOR_CLASS = 16,
|
||||
VENDOR_OPTS = 17,
|
||||
INTERFACE_ID = 18,
|
||||
RECONF_MSG = 19,
|
||||
RECONF_ACCEPT = 20,
|
||||
};
|
||||
|
||||
enum DHCP6_STATUSES
|
||||
{
|
||||
SUCCESS = 0,
|
||||
UNSPEC_FAIL = 1,
|
||||
NOADDR_AVAIL=2,
|
||||
NO_BINDING = 3,
|
||||
NOT_ON_LINK = 4,
|
||||
USE_MULTICAST =5
|
||||
};
|
||||
|
||||
static struct option longopts[] = {
|
||||
{"ip", required_argument, 0, 'a' },
|
||||
{"server-id", required_argument, 0, 's' },
|
||||
{"client-id", required_argument, 0, 'c' },
|
||||
{"iface", required_argument, 0, 'n' },
|
||||
{"iaid", required_argument, 0, 'i' },
|
||||
{"dry-run", no_argument, 0, 'd' },
|
||||
{"help", no_argument, 0, 'h' },
|
||||
{0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
const short DHCP6_CLIENT_PORT = 546;
|
||||
const short DHCP6_SERVER_PORT = 547;
|
||||
|
||||
const char* DHCP6_MULTICAST_ADDRESS = "ff02::1:2";
|
||||
|
||||
struct dhcp6_option {
|
||||
uint16_t type;
|
||||
uint16_t len;
|
||||
char value[1024];
|
||||
};
|
||||
|
||||
struct dhcp6_iaaddr_option {
|
||||
uint16_t type;
|
||||
uint16_t len;
|
||||
struct in6_addr ip;
|
||||
uint32_t preferred_lifetime;
|
||||
uint32_t valid_lifetime;
|
||||
};
|
||||
|
||||
struct dhcp6_iana_option {
|
||||
uint16_t type;
|
||||
uint16_t len;
|
||||
uint32_t iaid;
|
||||
uint32_t t1;
|
||||
uint32_t t2;
|
||||
char options[1024];
|
||||
};
|
||||
|
||||
|
||||
struct dhcp6_packet {
|
||||
size_t len;
|
||||
char buf[2048];
|
||||
};
|
||||
|
||||
size_t pack_duid(const char* str, char* dst)
|
||||
{
|
||||
char* tmp = strdup(str);
|
||||
char* tmp_to_free = tmp;
|
||||
char *ptr;
|
||||
uint8_t write_pos = 0;
|
||||
while ((ptr = strtok (tmp, ":")))
|
||||
{
|
||||
dst[write_pos] = (uint8_t) strtol(ptr, NULL, 16);
|
||||
write_pos += 1;
|
||||
tmp = NULL;
|
||||
}
|
||||
|
||||
free(tmp_to_free);
|
||||
return write_pos;
|
||||
}
|
||||
|
||||
struct dhcp6_option create_client_id_option(const char* duid)
|
||||
{
|
||||
struct dhcp6_option option;
|
||||
option.type = htons(CLIENTID);
|
||||
bzero(option.value, sizeof(option.value));
|
||||
option.len = htons(pack_duid(duid, option.value));
|
||||
return option;
|
||||
}
|
||||
|
||||
struct dhcp6_option create_server_id_option(const char* duid)
|
||||
{
|
||||
struct dhcp6_option option;
|
||||
option.type = htons(SERVERID);
|
||||
bzero(option.value, sizeof(option.value));
|
||||
option.len = htons(pack_duid(duid, option.value));
|
||||
return option;
|
||||
}
|
||||
|
||||
struct dhcp6_iaaddr_option create_iaadr_option(const char* ip)
|
||||
{
|
||||
struct dhcp6_iaaddr_option result;
|
||||
result.type =htons(IAADDR);
|
||||
/* no suboptions needed here, so length is 24 */
|
||||
result.len = htons(24);
|
||||
result.preferred_lifetime = 0;
|
||||
result.valid_lifetime = 0;
|
||||
int s = inet_pton(AF_INET6, ip, &(result.ip));
|
||||
if (s <= 0) {
|
||||
if (s == 0)
|
||||
fprintf(stderr, "Not in presentation format");
|
||||
else
|
||||
perror("inet_pton");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
struct dhcp6_iana_option create_iana_option(const char * iaid, struct dhcp6_iaaddr_option ia_addr)
|
||||
{
|
||||
struct dhcp6_iana_option result;
|
||||
result.type = htons(IA_NA);
|
||||
result.iaid = htonl(atoi(iaid));
|
||||
result.t1 = 0;
|
||||
result.t2 = 0;
|
||||
result.len = htons(12 + ntohs(ia_addr.len) + 2 * sizeof(uint16_t));
|
||||
memcpy(result.options, &ia_addr, ntohs(ia_addr.len) + 2 * sizeof(uint16_t));
|
||||
return result;
|
||||
}
|
||||
|
||||
struct dhcp6_packet create_release_packet(const char* iaid, const char* ip, const char* client_id, const char* server_id)
|
||||
{
|
||||
struct dhcp6_packet result;
|
||||
bzero(result.buf, sizeof(result.buf));
|
||||
/* message_type */
|
||||
result.buf[0] = RELEASE;
|
||||
/* tx_id */
|
||||
bzero(result.buf+1, 3);
|
||||
|
||||
struct dhcp6_option client_option = create_client_id_option(client_id);
|
||||
struct dhcp6_option server_option = create_server_id_option(server_id);
|
||||
struct dhcp6_iaaddr_option iaaddr_option = create_iaadr_option(ip);
|
||||
struct dhcp6_iana_option iana_option = create_iana_option(iaid, iaaddr_option);
|
||||
int offset = 4;
|
||||
memcpy(result.buf + offset, &client_option, ntohs(client_option.len) + 2*sizeof(uint16_t));
|
||||
offset += (ntohs(client_option.len)+ 2 *sizeof(uint16_t) );
|
||||
memcpy(result.buf + offset, &server_option, ntohs(server_option.len) + 2*sizeof(uint16_t) );
|
||||
offset += (ntohs(server_option.len)+ 2* sizeof(uint16_t));
|
||||
memcpy(result.buf + offset, &iana_option, ntohs(iana_option.len) + 2*sizeof(uint16_t) );
|
||||
offset += (ntohs(iana_option.len)+ 2* sizeof(uint16_t));
|
||||
result.len = offset;
|
||||
return result;
|
||||
}
|
||||
|
||||
uint16_t parse_iana_suboption(char* buf, size_t len)
|
||||
{
|
||||
size_t current_pos = 0;
|
||||
char option_value[1024];
|
||||
while (current_pos < len)
|
||||
{
|
||||
uint16_t option_type, option_len;
|
||||
memcpy(&option_type,buf + current_pos, sizeof(uint16_t));
|
||||
memcpy(&option_len,buf + current_pos + sizeof(uint16_t), sizeof(uint16_t));
|
||||
option_type = ntohs(option_type);
|
||||
option_len = ntohs(option_len);
|
||||
current_pos += 2 * sizeof(uint16_t);
|
||||
if (option_type == STATUS_CODE)
|
||||
{
|
||||
uint16_t status;
|
||||
memcpy(&status, buf + current_pos, sizeof(uint16_t));
|
||||
status = ntohs(status);
|
||||
if (status != SUCCESS)
|
||||
{
|
||||
memcpy(option_value, buf + current_pos + sizeof(uint16_t) , option_len - sizeof(uint16_t));
|
||||
option_value[option_len-sizeof(uint16_t)] ='\0';
|
||||
fprintf(stderr, "Error: %s\n", option_value);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
return -2;
|
||||
}
|
||||
|
||||
int16_t parse_packet(char* buf, size_t len)
|
||||
{
|
||||
int16_t ret = -1;
|
||||
uint8_t type = buf[0];
|
||||
/*skipping tx id. you need it, uncomment following line
|
||||
uint16_t tx_id = ntohs((buf[1] <<16) + (buf[2] <<8) + buf[3]);
|
||||
*/
|
||||
size_t current_pos = 4;
|
||||
if (type != REPLY )
|
||||
return NOT_REPLY_CODE;
|
||||
|
||||
char option_value[1024];
|
||||
while (current_pos < len)
|
||||
{
|
||||
uint16_t option_type, option_len;
|
||||
memcpy(&option_type,buf + current_pos, sizeof(uint16_t));
|
||||
memcpy(&option_len,buf + current_pos + sizeof(uint16_t), sizeof(uint16_t));
|
||||
option_type = ntohs(option_type);
|
||||
option_len = ntohs(option_len);
|
||||
current_pos += 2 * sizeof(uint16_t);
|
||||
if (option_type == STATUS_CODE)
|
||||
{
|
||||
uint16_t status;
|
||||
memcpy(&status, buf + current_pos, sizeof(uint16_t));
|
||||
status = ntohs(status);
|
||||
if (status != SUCCESS)
|
||||
{
|
||||
memcpy(option_value, buf + current_pos +sizeof(uint16_t) , option_len -sizeof(uint16_t));
|
||||
fprintf(stderr, "Error: %d %s\n", status, option_value);
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Got success status, return that if there's no specific error in an IA_NA. */
|
||||
ret = SUCCESS;
|
||||
}
|
||||
|
||||
if (option_type == IA_NA )
|
||||
{
|
||||
uint16_t result = parse_iana_suboption(buf + current_pos +24, option_len -24);
|
||||
if (result)
|
||||
return result;
|
||||
}
|
||||
|
||||
current_pos += option_len;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void usage(const char* arg, FILE* stream)
|
||||
{
|
||||
const char* usage_string ="--ip IPv6 --iface IFACE --server-id SERVER_ID --client-id CLIENT_ID --iaid IAID [--dry-run] | --help";
|
||||
fprintf (stream, "Usage: %s %s\n", arg, usage_string);
|
||||
}
|
||||
|
||||
static void fail_fatal(const char *errstr, int exitcode)
|
||||
{
|
||||
perror(errstr);
|
||||
exit(exitcode);
|
||||
}
|
||||
|
||||
int send_release_packet(const char* iface, struct dhcp6_packet* packet)
|
||||
{
|
||||
struct sockaddr_in6 server_addr, client_addr;
|
||||
char response[1400];
|
||||
int sock = socket(PF_INET6, SOCK_DGRAM, 0);
|
||||
int i = 0;
|
||||
if (sock < 0)
|
||||
{
|
||||
perror("creating socket");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (setsockopt(sock, SOL_SOCKET, 25, iface, strlen(iface)) == -1)
|
||||
{
|
||||
perror("SO_BINDTODEVICE");
|
||||
close(sock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&server_addr, 0, sizeof(server_addr));
|
||||
server_addr.sin6_family = AF_INET6;
|
||||
client_addr.sin6_family = AF_INET6;
|
||||
client_addr.sin6_port = htons(DHCP6_CLIENT_PORT);
|
||||
client_addr.sin6_flowinfo = 0;
|
||||
client_addr.sin6_scope_id =0;
|
||||
if (inet_pton(AF_INET6, "::", &client_addr.sin6_addr) <= 0)
|
||||
fail_fatal("inet_pton", 5);
|
||||
if (bind(sock, (struct sockaddr*)&client_addr, sizeof(struct sockaddr_in6)) != 0)
|
||||
perror("bind"); /* continue on bind error */
|
||||
if (inet_pton(AF_INET6, DHCP6_MULTICAST_ADDRESS, &server_addr.sin6_addr) <= 0)
|
||||
fail_fatal("inet_pton", 5);
|
||||
server_addr.sin6_port = htons(DHCP6_SERVER_PORT);
|
||||
ssize_t recv_size = 0;
|
||||
int result;
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
if (sendto(sock, packet->buf, packet->len, 0, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
|
||||
fail_fatal("sendto failed", 4);
|
||||
|
||||
recv_size = recvfrom(sock, response, sizeof(response), MSG_DONTWAIT, NULL, 0);
|
||||
if (recv_size == -1)
|
||||
{
|
||||
if (errno == EAGAIN)
|
||||
{
|
||||
sleep(1);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
perror("recvfrom");
|
||||
result = UNSPEC_FAIL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = parse_packet(response, recv_size);
|
||||
if (result == NOT_REPLY_CODE)
|
||||
{
|
||||
sleep(1);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
close(sock);
|
||||
return result;
|
||||
}
|
||||
|
||||
close(sock);
|
||||
fprintf(stderr, "Response timed out\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char * const argv[])
|
||||
{
|
||||
const char* UNINITIALIZED = "";
|
||||
const char* iface = UNINITIALIZED;
|
||||
const char* ip = UNINITIALIZED;
|
||||
const char* client_id = UNINITIALIZED;
|
||||
const char* server_id = UNINITIALIZED;
|
||||
const char* iaid = UNINITIALIZED;
|
||||
int dry_run = 0;
|
||||
while (1)
|
||||
{
|
||||
int option_index = 0;
|
||||
int c = getopt_long(argc, argv, "a:s:c:n:i:hd", longopts, &option_index);
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch(c)
|
||||
{
|
||||
case 0:
|
||||
if (longopts[option_index].flag !=0)
|
||||
break;
|
||||
|
||||
printf ("option %s", longopts[option_index].name);
|
||||
if (optarg)
|
||||
printf (" with arg %s", optarg);
|
||||
printf ("\n");
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
iaid = optarg;
|
||||
break;
|
||||
case 'n':
|
||||
iface = optarg;
|
||||
break;
|
||||
case 'a':
|
||||
ip = optarg;
|
||||
break;
|
||||
case 'c':
|
||||
client_id = optarg;
|
||||
break;
|
||||
case 'd':
|
||||
dry_run = 1;
|
||||
break;
|
||||
case 's':
|
||||
server_id = optarg;
|
||||
break;
|
||||
case 'h':
|
||||
usage(argv[0], stdout);
|
||||
return 0;
|
||||
case '?':
|
||||
usage(argv[0], stderr);
|
||||
return -1;
|
||||
default:
|
||||
abort();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (iaid == UNINITIALIZED)
|
||||
{
|
||||
fprintf(stderr, "Missing required iaid parameter\n");
|
||||
usage(argv[0], stderr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (server_id == UNINITIALIZED)
|
||||
{
|
||||
fprintf(stderr, "Missing required server-id parameter\n");
|
||||
usage(argv[0], stderr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (client_id == UNINITIALIZED)
|
||||
{
|
||||
fprintf(stderr, "Missing required client-id parameter\n");
|
||||
usage(argv[0], stderr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ip == UNINITIALIZED)
|
||||
{
|
||||
fprintf(stderr, "Missing required ip parameter\n");
|
||||
usage(argv[0], stderr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (iface == UNINITIALIZED)
|
||||
{
|
||||
fprintf(stderr, "Missing required iface parameter\n");
|
||||
usage(argv[0], stderr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct dhcp6_packet packet = create_release_packet(iaid, ip, client_id, server_id);
|
||||
|
||||
if (dry_run)
|
||||
{
|
||||
uint16_t i;
|
||||
|
||||
for(i=0; i<packet.len; i++)
|
||||
printf("%hhx", packet.buf[i]);
|
||||
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return send_release_packet(iface, &packet);
|
||||
}
|
||||
695
contrib/leasequery/leasequery.c
Normal file
695
contrib/leasequery/leasequery.c
Normal file
@@ -0,0 +1,695 @@
|
||||
/* leasequery is Copyright (c) 2025 Simon Kelley
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 dated June, 1991, or
|
||||
(at your option) version 3 dated 29 June, 2007.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* Author's email: simon@thekelleys.org.uk */
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <limits.h>
|
||||
#include <net/if.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#include <netdb.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/capability.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <ctype.h>
|
||||
|
||||
typedef unsigned char u8;
|
||||
typedef unsigned short u16;
|
||||
typedef unsigned int u32;
|
||||
typedef unsigned long long u64;
|
||||
|
||||
#define INADDRSZ 4
|
||||
#define ADDRSTRLEN 46
|
||||
|
||||
#define option_len(opt) ((int)(((unsigned char *)(opt))[1]))
|
||||
#define option_ptr(opt, i) ((void *)&(((unsigned char *)(opt))[2u+(unsigned int)(i)]))
|
||||
|
||||
#define DHCP_CHADDR_MAX 16
|
||||
#define DHCP_SERVER_PORT 67
|
||||
#define DHCP_CLIENT_PORT 68
|
||||
#define BOOTREQUEST 1
|
||||
#define BOOTREPLY 2
|
||||
|
||||
#define DHCP_COOKIE 0x63825363
|
||||
|
||||
#define DHCPLEASEQUERY 10
|
||||
#define DHCPLEASEUNASSIGNED 11
|
||||
#define DHCPLEASEUNKNOWN 12
|
||||
#define DHCPLEASEACTIVE 13
|
||||
|
||||
#define OPTION_END 255
|
||||
#define OPTION_ROUTER 3
|
||||
#define OPTION_VENDOR_CLASS_OPT 43
|
||||
#define OPTION_LEASE_TIME 51
|
||||
#define OPTION_MESSAGE_TYPE 53
|
||||
#define OPTION_SERVER_IDENTIFIER 54
|
||||
#define OPTION_REQUESTED_OPTIONS 55
|
||||
#define OPTION_VENDOR_ID 60
|
||||
#define OPTION_CLIENT_ID 61
|
||||
|
||||
/* flags in top of length field for DHCP-option tables */
|
||||
#define OT_ADDR_LIST 0x8000
|
||||
#define OT_RFC1035_NAME 0x4000
|
||||
#define OT_INTERNAL 0x2000
|
||||
#define OT_NAME 0x1000
|
||||
#define OT_CSTRING 0x0800
|
||||
#define OT_DEC 0x0400
|
||||
#define OT_TIME 0x0200
|
||||
|
||||
#define GETSHORT(s, cp) do { \
|
||||
unsigned char *t_cp = (unsigned char *)(cp); \
|
||||
(s) = ((u16)t_cp[0] << 8) \
|
||||
| ((u16)t_cp[1]) \
|
||||
; \
|
||||
(cp) += 2; \
|
||||
} while(0)
|
||||
|
||||
#define GETLONG(l, cp) do { \
|
||||
unsigned char *t_cp = (unsigned char *)(cp); \
|
||||
(l) = ((u32)t_cp[0] << 24) \
|
||||
| ((u32)t_cp[1] << 16) \
|
||||
| ((u32)t_cp[2] << 8) \
|
||||
| ((u32)t_cp[3]) \
|
||||
; \
|
||||
(cp) += 4; \
|
||||
} while (0)
|
||||
|
||||
#define PUTSHORT(s, cp) do { \
|
||||
u16 t_s = (u16)(s); \
|
||||
unsigned char *t_cp = (unsigned char *)(cp); \
|
||||
*t_cp++ = t_s >> 8; \
|
||||
*t_cp = t_s; \
|
||||
(cp) += 2; \
|
||||
} while(0)
|
||||
|
||||
#define PUTLONG(l, cp) do { \
|
||||
u32 t_l = (u32)(l); \
|
||||
unsigned char *t_cp = (unsigned char *)(cp); \
|
||||
*t_cp++ = t_l >> 24; \
|
||||
*t_cp++ = t_l >> 16; \
|
||||
*t_cp++ = t_l >> 8; \
|
||||
*t_cp = t_l; \
|
||||
(cp) += 4; \
|
||||
} while (0)
|
||||
|
||||
union all_addr {
|
||||
struct in_addr addr4;
|
||||
struct in6_addr addr6;
|
||||
};
|
||||
|
||||
struct dhcp_packet_with_opts{
|
||||
struct dhcp_packet {
|
||||
unsigned char op, htype, hlen, hops;
|
||||
unsigned int xid;
|
||||
unsigned short secs, flags;
|
||||
struct in_addr ciaddr, yiaddr, siaddr, giaddr;
|
||||
unsigned char chaddr[DHCP_CHADDR_MAX], sname[64], file[128];
|
||||
} header;
|
||||
unsigned char options[312];
|
||||
};
|
||||
|
||||
static const struct opttab_t {
|
||||
char *name;
|
||||
u16 val, size;
|
||||
} opttab[] = {
|
||||
{ "netmask", 1, OT_ADDR_LIST },
|
||||
{ "time-offset", 2, 4 },
|
||||
{ "router", 3, OT_ADDR_LIST },
|
||||
{ "dns-server", 6, OT_ADDR_LIST },
|
||||
{ "log-server", 7, OT_ADDR_LIST },
|
||||
{ "lpr-server", 9, OT_ADDR_LIST },
|
||||
{ "hostname", 12, OT_INTERNAL | OT_NAME },
|
||||
{ "boot-file-size", 13, 2 | OT_DEC },
|
||||
{ "domain-name", 15, OT_NAME },
|
||||
{ "swap-server", 16, OT_ADDR_LIST },
|
||||
{ "root-path", 17, OT_NAME },
|
||||
{ "extension-path", 18, OT_NAME },
|
||||
{ "ip-forward-enable", 19, 1 },
|
||||
{ "non-local-source-routing", 20, 1 },
|
||||
{ "policy-filter", 21, OT_ADDR_LIST },
|
||||
{ "max-datagram-reassembly", 22, 2 | OT_DEC },
|
||||
{ "default-ttl", 23, 1 | OT_DEC },
|
||||
{ "mtu", 26, 2 | OT_DEC },
|
||||
{ "all-subnets-local", 27, 1 },
|
||||
{ "broadcast", 28, OT_INTERNAL | OT_ADDR_LIST },
|
||||
{ "router-discovery", 31, 1 },
|
||||
{ "router-solicitation", 32, OT_ADDR_LIST },
|
||||
{ "static-route", 33, OT_ADDR_LIST },
|
||||
{ "trailer-encapsulation", 34, 1 },
|
||||
{ "arp-timeout", 35, 4 | OT_DEC },
|
||||
{ "ethernet-encap", 36, 1 },
|
||||
{ "tcp-ttl", 37, 1 },
|
||||
{ "tcp-keepalive", 38, 4 | OT_DEC },
|
||||
{ "nis-domain", 40, OT_NAME },
|
||||
{ "nis-server", 41, OT_ADDR_LIST },
|
||||
{ "ntp-server", 42, OT_ADDR_LIST },
|
||||
{ "vendor-encap", 43, OT_INTERNAL },
|
||||
{ "netbios-ns", 44, OT_ADDR_LIST },
|
||||
{ "netbios-dd", 45, OT_ADDR_LIST },
|
||||
{ "netbios-nodetype", 46, 1 },
|
||||
{ "netbios-scope", 47, 0 },
|
||||
{ "x-windows-fs", 48, OT_ADDR_LIST },
|
||||
{ "x-windows-dm", 49, OT_ADDR_LIST },
|
||||
{ "requested-address", 50, OT_INTERNAL | OT_ADDR_LIST },
|
||||
{ "lease-time", 51, OT_INTERNAL | OT_TIME },
|
||||
{ "option-overload", 52, OT_INTERNAL },
|
||||
{ "message-type", 53, OT_INTERNAL | OT_DEC },
|
||||
{ "server-identifier", 54, OT_INTERNAL | OT_ADDR_LIST },
|
||||
{ "parameter-request", 55, OT_INTERNAL },
|
||||
{ "message", 56, OT_INTERNAL },
|
||||
{ "max-message-size", 57, OT_INTERNAL },
|
||||
{ "T1", 58, OT_TIME},
|
||||
{ "T2", 59, OT_TIME},
|
||||
{ "vendor-class", 60, OT_NAME },
|
||||
{ "client-id", 61, OT_INTERNAL },
|
||||
{ "nis+-domain", 64, OT_NAME },
|
||||
{ "nis+-server", 65, OT_ADDR_LIST },
|
||||
{ "tftp-server", 66, OT_NAME },
|
||||
{ "bootfile-name", 67, OT_NAME },
|
||||
{ "mobile-ip-home", 68, OT_ADDR_LIST },
|
||||
{ "smtp-server", 69, OT_ADDR_LIST },
|
||||
{ "pop3-server", 70, OT_ADDR_LIST },
|
||||
{ "nntp-server", 71, OT_ADDR_LIST },
|
||||
{ "irc-server", 74, OT_ADDR_LIST },
|
||||
{ "user-class", 77, 0 },
|
||||
{ "rapid-commit", 80, 0 },
|
||||
{ "FQDN", 81, OT_INTERNAL },
|
||||
{ "agent-info", 82, OT_INTERNAL },
|
||||
{ "last-transaction", 91, 4 | OT_TIME },
|
||||
{ "associated-ip", 92, OT_ADDR_LIST },
|
||||
{ "client-arch", 93, 2 | OT_DEC },
|
||||
{ "client-interface-id", 94, 0 },
|
||||
{ "client-machine-id", 97, 0 },
|
||||
{ "posix-timezone", 100, OT_NAME }, /* RFC 4833, Sec. 2 */
|
||||
{ "tzdb-timezone", 101, OT_NAME }, /* RFC 4833, Sec. 2 */
|
||||
{ "ipv6-only", 108, 4 | OT_DEC }, /* RFC 8925 */
|
||||
{ "subnet-select", 118, OT_INTERNAL },
|
||||
{ "domain-search", 119, OT_RFC1035_NAME },
|
||||
{ "sip-server", 120, 0 },
|
||||
{ "classless-static-route", 121, 0 },
|
||||
{ "vendor-id-encap", 125, 0 },
|
||||
{ "tftp-server-address", 150, OT_ADDR_LIST },
|
||||
{ "server-ip-address", 255, OT_ADDR_LIST }, /* special, internal only, sets siaddr */
|
||||
{ NULL, 0, 0 }
|
||||
};
|
||||
|
||||
static void prettyprint_time(char *buf, unsigned int t);
|
||||
static char *print_mac(char *buff, unsigned char *mac, int len);
|
||||
|
||||
int lookup_dhcp_opt(char *name)
|
||||
{
|
||||
const struct opttab_t *t = opttab;
|
||||
int i;
|
||||
|
||||
for (i = 0; t[i].name; i++)
|
||||
if (strcasecmp(t[i].name, name) == 0)
|
||||
return t[i].val;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *option_string(unsigned int opt, unsigned char *val, int opt_len, char *buf, int buf_len)
|
||||
{
|
||||
int o, i, j, nodecode = 0;
|
||||
const struct opttab_t *ot = opttab;
|
||||
char addrbuff[ADDRSTRLEN];
|
||||
|
||||
for (o = 0; ot[o].name; o++)
|
||||
if (ot[o].val == opt)
|
||||
{
|
||||
if (buf)
|
||||
{
|
||||
memset(buf, 0, buf_len);
|
||||
|
||||
if (ot[o].size & OT_ADDR_LIST)
|
||||
{
|
||||
union all_addr addr;
|
||||
int addr_len = INADDRSZ;
|
||||
|
||||
for (buf[0]= 0, i = 0; i <= opt_len - addr_len; i += addr_len)
|
||||
{
|
||||
if (i != 0)
|
||||
strncat(buf, ", ", buf_len - strlen(buf));
|
||||
/* align */
|
||||
memcpy(&addr, &val[i], addr_len);
|
||||
inet_ntop(AF_INET, &val[i], addrbuff, ADDRSTRLEN);
|
||||
strncat(buf, addrbuff, buf_len - strlen(buf));
|
||||
}
|
||||
}
|
||||
else if (ot[o].size & OT_NAME)
|
||||
for (i = 0, j = 0; i < opt_len && j < buf_len ; i++)
|
||||
{
|
||||
char c = val[i];
|
||||
if (isprint((unsigned char)c))
|
||||
buf[j++] = c;
|
||||
}
|
||||
else if ((ot[o].size & (OT_DEC | OT_TIME)) && opt_len != 0)
|
||||
{
|
||||
unsigned int dec = 0;
|
||||
|
||||
for (i = 0; i < opt_len; i++)
|
||||
dec = (dec << 8) | val[i];
|
||||
|
||||
if (ot[o].size & OT_TIME)
|
||||
prettyprint_time(buf, dec);
|
||||
else
|
||||
sprintf(buf, "%u", dec);
|
||||
}
|
||||
else
|
||||
nodecode = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (opt_len != 0 && buf && (!ot[o].name || nodecode))
|
||||
{
|
||||
int trunc = 0;
|
||||
if (opt_len > 14)
|
||||
{
|
||||
trunc = 1;
|
||||
opt_len = 14;
|
||||
}
|
||||
print_mac(buf, val, opt_len);
|
||||
if (trunc)
|
||||
strncat(buf, "...", buf_len - strlen(buf));
|
||||
|
||||
|
||||
}
|
||||
|
||||
return ot[o].name ? ot[o].name : "";
|
||||
|
||||
}
|
||||
|
||||
static void prettyprint_time(char *buf, unsigned int t)
|
||||
{
|
||||
if (t == 0xffffffff)
|
||||
sprintf(buf, "infinite");
|
||||
else
|
||||
{
|
||||
unsigned int x, p = 0;
|
||||
if ((x = t/86400))
|
||||
p += sprintf(&buf[p], "%ud", x);
|
||||
if ((x = (t/3600)%24))
|
||||
p += sprintf(&buf[p], "%uh", x);
|
||||
if ((x = (t/60)%60))
|
||||
p += sprintf(&buf[p], "%um", x);
|
||||
if ((x = t%60))
|
||||
sprintf(&buf[p], "%us", x);
|
||||
}
|
||||
}
|
||||
|
||||
static char *print_mac(char *buff, unsigned char *mac, int len)
|
||||
{
|
||||
char *p = buff;
|
||||
int i;
|
||||
|
||||
if (len == 0)
|
||||
sprintf(p, "<null>");
|
||||
else
|
||||
for (i = 0; i < len; i++)
|
||||
p += sprintf(p, "%.2x%s", mac[i], (i == len - 1) ? "" : ":");
|
||||
|
||||
return buff;
|
||||
}
|
||||
|
||||
static unsigned char *dhcp_skip_opts(struct dhcp_packet_with_opts *pktp)
|
||||
{
|
||||
unsigned char *start = (unsigned char *)(((unsigned int *)&pktp->options[0]) + 1);
|
||||
while (*start != 0)
|
||||
start += start[1] + 2;
|
||||
return start;
|
||||
}
|
||||
|
||||
static unsigned char *dhcp_find_opt(struct dhcp_packet_with_opts *pktp, int optno)
|
||||
{
|
||||
unsigned char *start = (unsigned char *)(((unsigned int *)&pktp->options[0]) + 1);
|
||||
while (*start != OPTION_END)
|
||||
{
|
||||
if (*start == optno)
|
||||
return start;
|
||||
start += start[1] + 2;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void option_put(struct dhcp_packet_with_opts *pktp, int opt, int len, unsigned int val)
|
||||
{
|
||||
int i;
|
||||
unsigned char *p = dhcp_skip_opts(pktp);
|
||||
|
||||
if (p)
|
||||
{
|
||||
*p++ = opt;
|
||||
*p++ = len;
|
||||
for (i = 0; i < len; i++)
|
||||
*(p++) = val >> (8 * (len - (i + 1)));
|
||||
}
|
||||
}
|
||||
|
||||
static void option_put_string(struct dhcp_packet_with_opts *pktp, int opt,
|
||||
const char *string, int null_term)
|
||||
{
|
||||
unsigned char *p;
|
||||
size_t len = strlen(string);
|
||||
|
||||
if (null_term && len != 255)
|
||||
len++;
|
||||
|
||||
if ((p = dhcp_skip_opts(pktp)))
|
||||
{
|
||||
*p++ = opt;
|
||||
*p++ = len;
|
||||
memcpy(p, string, len);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* in may equal out, when maxlen may be -1 (No max len).
|
||||
Return -1 for extraneous no-hex chars found. */
|
||||
int parse_hex(char *in, unsigned char *out, int maxlen,
|
||||
unsigned int *wildcard_mask, int *mac_type)
|
||||
{
|
||||
int done = 0, mask = 0, i = 0;
|
||||
char *r;
|
||||
|
||||
if (mac_type)
|
||||
*mac_type = 0;
|
||||
|
||||
while (!done && (maxlen == -1 || i < maxlen))
|
||||
{
|
||||
for (r = in; *r != 0 && *r != ':' && *r != '-' && *r != ' '; r++)
|
||||
if (*r != '*' && !isxdigit((unsigned char)*r))
|
||||
return -1;
|
||||
|
||||
if (*r == 0)
|
||||
done = 1;
|
||||
|
||||
if (r != in )
|
||||
{
|
||||
if (*r == '-' && i == 0 && mac_type)
|
||||
{
|
||||
*r = 0;
|
||||
*mac_type = strtol(in, NULL, 16);
|
||||
mac_type = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
*r = 0;
|
||||
if (strcmp(in, "*") == 0)
|
||||
{
|
||||
mask = (mask << 1) | 1;
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
int j, bytes = (1 + (r - in))/2;
|
||||
for (j = 0; j < bytes; j++)
|
||||
{
|
||||
char sav;
|
||||
if (j < bytes - 1)
|
||||
{
|
||||
sav = in[(j+1)*2];
|
||||
in[(j+1)*2] = 0;
|
||||
}
|
||||
/* checks above allow mix of hexdigit and *, which
|
||||
is illegal. */
|
||||
if (strchr(&in[j*2], '*'))
|
||||
return -1;
|
||||
out[i] = strtol(&in[j*2], NULL, 16);
|
||||
mask = mask << 1;
|
||||
if (++i == maxlen)
|
||||
break;
|
||||
if (j < bytes - 1)
|
||||
in[(j+1)*2] = sav;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
in = r+1;
|
||||
}
|
||||
|
||||
if (wildcard_mask)
|
||||
*wildcard_mask = mask;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static char *split_chr(char *s, char c)
|
||||
{
|
||||
char *comma, *p;
|
||||
|
||||
if (!s || !(comma = strchr(s, c)))
|
||||
return NULL;
|
||||
|
||||
p = comma;
|
||||
*comma = ' ';
|
||||
|
||||
for (; *comma == ' '; comma++);
|
||||
|
||||
for (; (p >= s) && *p == ' '; p--)
|
||||
*p = 0;
|
||||
|
||||
return comma;
|
||||
}
|
||||
|
||||
static char *split(char *s)
|
||||
{
|
||||
return split_chr(s, ',');
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int fd;
|
||||
struct ifreq ifr;
|
||||
struct in_addr iface_addr, server_addr, lease_addr;
|
||||
struct dhcp_packet_with_opts pkt;
|
||||
struct sockaddr_in saddr;
|
||||
unsigned char *p;
|
||||
ssize_t sz;
|
||||
unsigned char mac[DHCP_CHADDR_MAX], clid[256], req_options[256];
|
||||
char buff[500];
|
||||
int clid_len = 0, mac_len = 0, mac_type = 0, opts_len = 0;
|
||||
unsigned short port = DHCP_SERVER_PORT;
|
||||
unsigned int xid;
|
||||
struct timeval tv;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
srand(tv.tv_usec);
|
||||
xid = rand();
|
||||
server_addr.s_addr = lease_addr.s_addr = iface_addr.s_addr = 0;
|
||||
|
||||
if ((fd = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
|
||||
{
|
||||
perror("leasequery: cannot create socket");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
int option = getopt(argc, argv, "i:s:l:m:c:p:r:");
|
||||
|
||||
if (option == -1)
|
||||
break;
|
||||
|
||||
switch (option)
|
||||
{
|
||||
default:
|
||||
fprintf(stderr,
|
||||
"-p <port> port on DHCP server.\n"
|
||||
"-i <interface> exit interface to DHCP server.\n"
|
||||
"-s <inet-addr> DHCP server address.\n"
|
||||
"-l <inet-addr> Query lease by IP address.\n"
|
||||
"-m <MAC-addr> Query lease by MAC address.\n"
|
||||
"-c <hex> Query lease by client-id.\n"
|
||||
"-r <name>|<int>[,...] List of options to return.\n");
|
||||
exit(1);
|
||||
|
||||
case 'p':
|
||||
port = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
strncpy(ifr.ifr_name, optarg, IF_NAMESIZE);
|
||||
ifr.ifr_addr.sa_family = AF_INET;
|
||||
if (ioctl(fd, SIOCGIFADDR, &ifr) == -1)
|
||||
{
|
||||
perror("leasequery: cannot get interface address");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
iface_addr = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
if (inet_pton(AF_INET, optarg, &server_addr) <= 0)
|
||||
{
|
||||
fprintf(stderr, "leasequery: bad server address\n");
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
if (inet_pton(AF_INET, optarg, &lease_addr) <= 0)
|
||||
{
|
||||
fprintf(stderr, "leasequery: bad lease address\n");
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
mac_type = 1; /* default ethernet */
|
||||
mac_len = parse_hex(optarg, mac, DHCP_CHADDR_MAX, NULL, &mac_type);
|
||||
if (!mac_type)
|
||||
mac_type = 1; /* default ethernet */
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
clid_len = parse_hex(optarg, clid, 256, NULL, NULL);
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
{
|
||||
char *comma;
|
||||
int opt;
|
||||
|
||||
while (optarg)
|
||||
{
|
||||
comma = split(optarg);
|
||||
|
||||
if ((opt = lookup_dhcp_opt(optarg)) != -1 || (opt = atoi(optarg)) != 0)
|
||||
req_options[opts_len++] = opt;
|
||||
|
||||
optarg = comma;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!server_addr.s_addr)
|
||||
{
|
||||
fprintf(stderr, "leasequery: no server address\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(&pkt, 0, sizeof pkt);
|
||||
pkt.header.op = BOOTREQUEST;
|
||||
pkt.header.xid = xid;
|
||||
pkt.header.ciaddr = lease_addr;
|
||||
pkt.header.hlen = mac_len;
|
||||
pkt.header.htype = mac_type;
|
||||
memcpy(pkt.header.chaddr, mac, mac_len);
|
||||
*((unsigned int *)&pkt.options[0]) = htonl(DHCP_COOKIE);
|
||||
|
||||
/* Dnsmasq extension. */
|
||||
pkt.header.giaddr.s_addr = iface_addr.s_addr ? iface_addr.s_addr : INADDR_BROADCAST;
|
||||
|
||||
option_put(&pkt, OPTION_MESSAGE_TYPE, 1, DHCPLEASEQUERY);
|
||||
|
||||
if (clid_len != 0)
|
||||
{
|
||||
p = dhcp_skip_opts(&pkt);
|
||||
*p++ = OPTION_CLIENT_ID;
|
||||
*p++ = clid_len;
|
||||
memcpy(p, clid, clid_len);
|
||||
}
|
||||
|
||||
if (opts_len != 0)
|
||||
{
|
||||
p = dhcp_skip_opts(&pkt);
|
||||
*p++ = OPTION_REQUESTED_OPTIONS;
|
||||
*p++ = opts_len;
|
||||
memcpy(p, req_options, opts_len);
|
||||
}
|
||||
|
||||
if (iface_addr.s_addr)
|
||||
{
|
||||
saddr.sin_family = AF_INET;
|
||||
saddr.sin_port = htons(port);
|
||||
saddr.sin_addr.s_addr = iface_addr.s_addr;
|
||||
|
||||
if (bind(fd, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in)))
|
||||
{
|
||||
perror("leasequery: cannot bind DHCP server socket");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
saddr.sin_family = AF_INET;
|
||||
saddr.sin_port = htons(port);
|
||||
saddr.sin_addr = server_addr;
|
||||
|
||||
while((sz = sendto(fd, &pkt, dhcp_skip_opts(&pkt) - ((unsigned char *)&pkt), 0, (struct sockaddr *)&saddr, sizeof(saddr))) == -1 &&
|
||||
errno == EINTR);
|
||||
|
||||
if (sz == -1)
|
||||
{
|
||||
perror("leasequery: sendto()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
sz = recv(fd, &pkt, sizeof(pkt), 0);
|
||||
|
||||
if (sz == -1)
|
||||
{
|
||||
perror("leasequery: recv()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (sz >= sizeof(pkt.header) &&
|
||||
pkt.header.op == BOOTREPLY &&
|
||||
(p = dhcp_find_opt(&pkt, OPTION_MESSAGE_TYPE)) &&
|
||||
pkt.header.xid == xid)
|
||||
{
|
||||
if (p[2] == DHCPLEASEUNASSIGNED)
|
||||
printf("UNASSIGNED\n");
|
||||
else if (p[2] == DHCPLEASEUNKNOWN)
|
||||
printf("UNKNOWN\n");
|
||||
else if (p[2] == DHCPLEASEACTIVE)
|
||||
{
|
||||
print_mac(buff, pkt.header.chaddr, pkt.header.hlen);
|
||||
printf("ACTIVE %s %s\n", inet_ntoa(pkt.header.ciaddr), buff);
|
||||
|
||||
p = (unsigned char *)(((unsigned int *)&pkt.options[0]) + 1);
|
||||
|
||||
while (*p != OPTION_END)
|
||||
{
|
||||
if (*p != OPTION_MESSAGE_TYPE)
|
||||
{
|
||||
char *optname = option_string(p[0], option_ptr(p, 0), option_len(p), buff, 500);
|
||||
|
||||
printf("size:%3d option:%3d %s %s\n", option_len(p), p[0], optname, buff);
|
||||
}
|
||||
p += p[1] + 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
36
contrib/mactable/macscript
Executable file
36
contrib/mactable/macscript
Executable file
@@ -0,0 +1,36 @@
|
||||
#!/bin/bash
|
||||
|
||||
STATUS_FILE="/tmp/dnsmasq-ip-mac.status"
|
||||
|
||||
# Script for dnsmasq lease-change hook.
|
||||
# Maintains the above file with an IP address/MAC address pairs,
|
||||
# one lease per line. Works with IPv4 and IPv6 leases, file is
|
||||
# atomically updated, so no races for users of the data.
|
||||
|
||||
action="$1"
|
||||
mac="$2" # IPv4
|
||||
ip="$3"
|
||||
|
||||
# ensure it always exists.
|
||||
|
||||
if [ ! -f "$STATUS_FILE" ]; then
|
||||
touch "$STATUS_FILE"
|
||||
fi
|
||||
|
||||
if [ -n "$DNSMASQ_IAID" ]; then
|
||||
mac="$DNSMASQ_MAC" # IPv6
|
||||
fi
|
||||
|
||||
# worry about an add or old action when the MAC address is not known:
|
||||
# leave any old one in place in that case.
|
||||
|
||||
if [ "$action" = "add" -o "$action" = "old" -o "$action" = "del" ]; then
|
||||
if [ -n "$mac" -o "$action" = "del" ]; then
|
||||
sed "/^${ip//./\.} / d" "$STATUS_FILE" > "$STATUS_FILE".new
|
||||
|
||||
if [ "$action" = "add" -o "$action" = "old" ]; then
|
||||
echo "$ip $mac" >> "$STATUS_FILE".new
|
||||
fi
|
||||
mv "$STATUS_FILE".new "$STATUS_FILE" # atomic update.
|
||||
fi
|
||||
fi
|
||||
78
contrib/port-forward/dnsmasq-portforward
Executable file
78
contrib/port-forward/dnsmasq-portforward
Executable file
@@ -0,0 +1,78 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# /usr/sbin/dnsmasq-portforward
|
||||
#
|
||||
# A script which gets run when the dnsmasq DHCP lease database changes.
|
||||
# It logs to $LOGFILE, if it exists, and maintains port-forwards using
|
||||
# IP-tables so that they always point to the correct host. See
|
||||
# $PORTSFILE for details on configuring this. dnsmasq must be version 2.34
|
||||
# or later.
|
||||
#
|
||||
# To enable this script, add
|
||||
# dhcp-script=/usr/sbin/dnsmasq-portforward
|
||||
# to /etc/dnsmasq.conf
|
||||
#
|
||||
# To enable logging, touch $LOGFILE
|
||||
#
|
||||
|
||||
PORTSFILE=/etc/portforward
|
||||
LOGFILE=/var/log/dhcp.log
|
||||
IPTABLES=/sbin/iptables
|
||||
|
||||
action=${1:-0}
|
||||
hostname=${4}
|
||||
|
||||
# log what's going on.
|
||||
if [ -f ${LOGFILE} ] ; then
|
||||
date +"%D %T $*" >>${LOGFILE}
|
||||
fi
|
||||
|
||||
# If a lease gets stripped of a name, we see that as an "old" action
|
||||
# with DNSMASQ_OLD_HOSTNAME set, convert it into a "del"
|
||||
if [ ${DNSMASQ_OLD_HOSTNAME} ] && [ ${action} = old ] ; then
|
||||
action=del
|
||||
hostname=${DNSMASQ_OLD_HOSTNAME}
|
||||
fi
|
||||
|
||||
# IPv6 leases are not our concern. no NAT there!
|
||||
if [ ${DNSMASQ_IAID} ] ; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# action init is not relevant, and will only be seen when leasefile-ro is set.
|
||||
if [ ${action} = init ] ; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# action tftp is not relevant.
|
||||
if [ ${action} = tftp ] ; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ ${hostname} ]; then
|
||||
ports=$(sed -n -e "/^${hostname}\ .*/ s/^.* //p" ${PORTSFILE})
|
||||
|
||||
for port in $ports; do
|
||||
verb=removed
|
||||
protocol=tcp
|
||||
if [ ${port:0:1} = u ] ; then
|
||||
protocol=udp
|
||||
port=${port/u/}
|
||||
fi
|
||||
src=${port/:*/}
|
||||
dst=${port/*:/}
|
||||
# delete first, to avoid multiple copies of rules.
|
||||
${IPTABLES} -t nat -D PREROUTING -p $protocol --destination-port $src -j DNAT --to-destination ${3}:$dst
|
||||
if [ ${action} != del ] ; then
|
||||
${IPTABLES} -t nat -A PREROUTING -p $protocol --destination-port $src -j DNAT --to-destination ${3}:$dst
|
||||
verb=added
|
||||
fi
|
||||
if [ -f ${LOGFILE} ] ; then
|
||||
echo " DNAT $protocol $src to ${3}:$dst ${verb}." >>${LOGFILE}
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
|
||||
28
contrib/port-forward/portforward
Normal file
28
contrib/port-forward/portforward
Normal file
@@ -0,0 +1,28 @@
|
||||
# This file is read by /usr/sbin/dnsmasq-portforward and used to set up port
|
||||
# forwarding to hostnames. If the dnsmasq-determined hostname matches the
|
||||
# first column of this file, then a DNAT port-forward will be set up
|
||||
# to the address which has just been allocated by DHCP . The second field
|
||||
# is port number(s). If there is only one, then the port-forward goes to
|
||||
# the same port on the DHCP-client, if there are two separated with a
|
||||
# colon, then the second number is the port to which the connection
|
||||
# is forwarded on the DHCP-client. By default, forwarding is set up
|
||||
# for TCP, but it can done for UDP instead by prefixing the port to "u".
|
||||
# To forward both TCP and UDP, two lines are required.
|
||||
#
|
||||
# eg.
|
||||
# wwwserver 80
|
||||
# will set up a port forward from port 80 on this host to port 80
|
||||
# at the address allocated to wwwserver whenever wwwserver gets a DHCP lease.
|
||||
#
|
||||
# wwwserver 8080:80
|
||||
# will set up a port forward from port 8080 on this host to port 80
|
||||
# on the DHCP-client.
|
||||
#
|
||||
# dnsserver 53
|
||||
# dnsserver u53
|
||||
# will port forward port 53 UDP and TCP from this host to port 53 on dnsserver.
|
||||
#
|
||||
# Port forwards will recreated when dnsmasq restarts after a reboot, and
|
||||
# removed when DHCP leases expire. After editing this file, send
|
||||
# SIGHUP to dnsmasq to install new iptables entries in the kernel.
|
||||
|
||||
18
contrib/reverse-dns/README
Normal file
18
contrib/reverse-dns/README
Normal file
@@ -0,0 +1,18 @@
|
||||
The script reads stdin and replaces all IP addresses with names before
|
||||
outputting it again. IPs from private networks are reverse looked up
|
||||
via dns. Other IP addresses are searched for in the dnsmasq query log.
|
||||
This gives names (CNAMEs if I understand DNS correctly) that are closer
|
||||
to the name the client originally asked for then the names obtained by
|
||||
reverse lookup. Just run
|
||||
|
||||
netstat -n -4 | ./reverse_replace.sh
|
||||
|
||||
to see what it does. It needs
|
||||
|
||||
log-queries
|
||||
log-facility=/var/log/dnsmasq.log
|
||||
|
||||
in the dnsmasq configuration.
|
||||
|
||||
The script runs on debian (with dash installed) and on busybox.
|
||||
|
||||
125
contrib/reverse-dns/reverse_replace.sh
Normal file
125
contrib/reverse-dns/reverse_replace.sh
Normal file
@@ -0,0 +1,125 @@
|
||||
#!/bin/dash
|
||||
# $Id: reverse_replace.sh 18 2015-03-01 16:12:35Z jo $
|
||||
#
|
||||
# Usage e.g.: netstat -n -4 | reverse_replace.sh
|
||||
# Parses stdin for IP4 addresses and replaces them
|
||||
# with names retrieved by parsing the dnsmasq log.
|
||||
# This currently only gives CNAMEs. But these
|
||||
# usually tell you more than the ones from reverse
|
||||
# lookups.
|
||||
#
|
||||
# This has been tested on debian and asuswrt. Please
|
||||
# report successful tests on other platforms.
|
||||
#
|
||||
# Author: Joachim Zobel <jz-2014@heute-morgen.de>
|
||||
# License: Consider this MIT style licensed. You can
|
||||
# do as you ike, but you must not remove my name.
|
||||
#
|
||||
|
||||
LOG=/var/log/dnsmasq.log
|
||||
MAX_LINES=15000
|
||||
|
||||
# sed regex do match IPs
|
||||
IP_regex='[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}'
|
||||
# private IP ranges
|
||||
IP_private='\(^127\.\)\|\(^192\.168\.\)\|\(^10\.\)\|\(^172\.1[6-9]\.\)\|\(^172\.2[0-9]\.\)\|\(^172\.3[0-1]\.\)'
|
||||
|
||||
#######################################################################
|
||||
# Find Commands
|
||||
|
||||
HOST=nslookup
|
||||
if type host > /dev/null 2>&1; then
|
||||
# echo "No need for nslookup, host is there"
|
||||
HOST=host
|
||||
fi
|
||||
|
||||
#######################################################################
|
||||
# Functions
|
||||
|
||||
# Use shell variables for an (IP) lookup table
|
||||
create_lookup_table()
|
||||
{
|
||||
# Parse log into lookup table
|
||||
local CMDS="$( tail -"$MAX_LINES" "$LOG" | \
|
||||
grep " is $IP_regex" | \
|
||||
sed "s#.* \([^ ]*\) is \($IP_regex\).*#set_val \2 \1;#" )"
|
||||
|
||||
local IFS='
|
||||
'
|
||||
for CMD in $CMDS
|
||||
do
|
||||
eval $CMD
|
||||
done
|
||||
}
|
||||
|
||||
set_val()
|
||||
{
|
||||
local _IP=$(echo $1 | tr . _)
|
||||
local KEY="__IP__$_IP"
|
||||
eval "$KEY"=$2
|
||||
}
|
||||
|
||||
get_val()
|
||||
{
|
||||
local _IP=$(echo $1 | tr . _)
|
||||
local KEY="__IP__$_IP"
|
||||
eval echo -n '${'"$KEY"'}'
|
||||
}
|
||||
|
||||
dns_lookup()
|
||||
{
|
||||
local IP=$1
|
||||
|
||||
local RTN="$($HOST $IP | \
|
||||
sed 's#\s\+#\n#g' | \
|
||||
grep -v '^$' | \
|
||||
tail -1 | tr -d '\n' | \
|
||||
sed 's#\.$##')"
|
||||
if echo $RTN | grep -q NXDOMAIN; then
|
||||
echo -n $IP
|
||||
else
|
||||
echo -n "$RTN"
|
||||
fi
|
||||
}
|
||||
|
||||
reverse_dns()
|
||||
{
|
||||
local IP=$1
|
||||
|
||||
# Skip if it is not an IP
|
||||
if ! echo $IP | grep -q "^$IP_regex$"; then
|
||||
echo -n $IP
|
||||
return
|
||||
fi
|
||||
|
||||
# Do a dns lookup, if it is a local IP
|
||||
if echo $IP | grep -q $IP_private; then
|
||||
dns_lookup $IP
|
||||
return
|
||||
fi
|
||||
|
||||
local NAME="$(get_val $IP)"
|
||||
|
||||
if [ -z "$NAME" ]; then
|
||||
echo -n $IP
|
||||
else
|
||||
echo -n $NAME
|
||||
fi
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
# Main
|
||||
create_lookup_table
|
||||
|
||||
while read LINE; do
|
||||
for IP in $(echo "$LINE" | \
|
||||
sed "s#\b\($IP_regex\)\b#\n\1\n#g" | \
|
||||
grep $IP_regex)
|
||||
do
|
||||
NAME=`reverse_dns $IP `
|
||||
# echo "$NAME $IP"
|
||||
LINE=`echo "$LINE" | sed "s#$IP#$NAME#" `
|
||||
done
|
||||
echo $LINE
|
||||
done
|
||||
|
||||
35
contrib/static-arp/static-arp
Normal file
35
contrib/static-arp/static-arp
Normal file
@@ -0,0 +1,35 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Contributed by Darren Hoo <darren.hoo@gmail.com>
|
||||
|
||||
# If you use dnsmasq as DHCP server on a router, you may have
|
||||
# met with attackers trying ARP Poison Routing (APR) on your
|
||||
# local area network. This script will setup a 'permanent' entry
|
||||
# in the router's ARP table upon each DHCP transaction so as to
|
||||
# make the attacker's efforts less successful.
|
||||
|
||||
# Usage:
|
||||
# edit /etc/dnsmasq.conf and specify the path of this script
|
||||
# to dhcp-script, for example:
|
||||
# dhcp-script=/usr/sbin/static-arp
|
||||
|
||||
# if $1 is add or old, update the static arp table entry.
|
||||
# if $1 is del, then delete the entry from the table
|
||||
# if $1 is init which is called by dnsmasq at startup, it's ignored
|
||||
|
||||
ARP=/usr/sbin/arp
|
||||
|
||||
# Arguments.
|
||||
# $1 is action (add, del, old)
|
||||
# $2 is MAC
|
||||
# $3 is address
|
||||
# $4 is hostname (optional, may be unset)
|
||||
|
||||
if [ ${1} = del ] ; then
|
||||
${ARP} -d $3
|
||||
fi
|
||||
|
||||
if [ ${1} = old ] || [ ${1} = add ] ; then
|
||||
${ARP} -s $3 $2
|
||||
fi
|
||||
|
||||
16
contrib/systemd/README
Normal file
16
contrib/systemd/README
Normal file
@@ -0,0 +1,16 @@
|
||||
Hello,
|
||||
|
||||
I created a systemd service file for dnsmasq.
|
||||
systemd is a sysvinit replacement (see [1] for more information).
|
||||
One of the goals of systemd is to encourage standardization between different
|
||||
distributions. This means, while I also submitted a ticket in Debian GNU/Linux,
|
||||
I would like to ask you to accept this service file as the upstream
|
||||
distributor, so that other distributions can use the same service file and
|
||||
don’t have to ship their own.
|
||||
|
||||
Please include this file in your next release (just like in init script).
|
||||
|
||||
|
||||
[1] http://en.wikipedia.org/wiki/Systemd
|
||||
|
||||
|
||||
57
contrib/systemd/dbus_activation
Normal file
57
contrib/systemd/dbus_activation
Normal file
@@ -0,0 +1,57 @@
|
||||
To: dnsmasq-discuss@lists.thekelleys.org.uk
|
||||
From: Alex Elsayed <eternaleye+usenet@gmail.com>
|
||||
Date: Tue, 15 May 2012 01:53:54 -0700
|
||||
Subject: [Dnsmasq-discuss] [PATCH] Support dbus activation
|
||||
|
||||
Introduce dbus service file and turn dbus on in the systemd
|
||||
unit.
|
||||
|
||||
Note to packagers:
|
||||
To add support for dbus activation, you must install the dbus
|
||||
service file (dbus/uk.org.thekelleys.dnsmasq.service) into
|
||||
$DATADIR/dbus-1/system-services.
|
||||
|
||||
---
|
||||
contrib/systemd/dnsmasq.service | 2 +-
|
||||
dbus/uk.org.thekelleys.dnsmasq.service | 7 +++++++
|
||||
2 files changed, 8 insertions(+), 1 deletion(-)
|
||||
create mode 100644 dbus/uk.org.thekelleys.dnsmasq.service
|
||||
|
||||
diff --git a/contrib/systemd/dnsmasq.service
|
||||
b/contrib/systemd/dnsmasq.service
|
||||
index a27fe6d..4a784d3 100644
|
||||
--- a/contrib/systemd/dnsmasq.service
|
||||
+++ b/contrib/systemd/dnsmasq.service
|
||||
@@ -5,7 +5,7 @@ Description=A lightweight DHCP and caching DNS server
|
||||
Type=dbus
|
||||
BusName=uk.org.thekelleys.dnsmasq
|
||||
ExecStartPre=/usr/sbin/dnsmasq --test
|
||||
-ExecStart=/usr/sbin/dnsmasq -k
|
||||
+ExecStart=/usr/sbin/dnsmasq -k -1
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
|
||||
[Install]
|
||||
diff --git a/dbus/uk.org.thekelleys.dnsmasq.service
|
||||
b/dbus/uk.org.thekelleys.dnsmasq.service
|
||||
new file mode 100644
|
||||
index 0000000..f5fe98d
|
||||
--- /dev/null
|
||||
+++ b/dbus/uk.org.thekelleys.dnsmasq.service
|
||||
@@ -0,0 +1,7 @@
|
||||
+[D-BUS Service]
|
||||
+Name=uk.org.thekelleys.dnsmasq
|
||||
+Exec=/usr/sbin/dnsmasq -k -1
|
||||
+User=root
|
||||
+SystemdService=dnsmasq.service
|
||||
+
|
||||
+
|
||||
--
|
||||
1.7.10.2
|
||||
|
||||
|
||||
|
||||
_______________________________________________
|
||||
Dnsmasq-discuss mailing list
|
||||
Dnsmasq-discuss@lists.thekelleys.org.uk
|
||||
http://lists.thekelleys.org.uk/mailman/listinfo/dnsmasq-discuss
|
||||
|
||||
15
contrib/systemd/dnsmasq.service
Normal file
15
contrib/systemd/dnsmasq.service
Normal file
@@ -0,0 +1,15 @@
|
||||
[Unit]
|
||||
Description=dnsmasq - A lightweight DHCP and caching DNS server
|
||||
After=network.target
|
||||
Before=network-online.target nss-lookup.target
|
||||
Wants=nss-lookup.target
|
||||
|
||||
[Service]
|
||||
Type=dbus
|
||||
BusName=uk.org.thekelleys.dnsmasq
|
||||
ExecStartPre=/usr/sbin/dnsmasq --test
|
||||
ExecStart=/usr/sbin/dnsmasq -k
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
19
contrib/try-all-ns/README
Normal file
19
contrib/try-all-ns/README
Normal file
@@ -0,0 +1,19 @@
|
||||
Date: Thu, 07 Dec 2006 00:41:43 -0500
|
||||
From: Bob Carroll <bob.carroll@rit.edu>
|
||||
Subject: dnsmasq suggestion
|
||||
To: simon@thekelleys.org.uk
|
||||
|
||||
|
||||
Hello,
|
||||
|
||||
I recently needed a feature in dnsmasq for a very bizarre situation. I
|
||||
placed a list of name servers in a special resolve file and told dnsmasq
|
||||
to use that. But I wanted it to try requests in order and treat NXDOMAIN
|
||||
requests as a failed tcp connection. I wrote the feature into dnsmasq
|
||||
and it seems to work. I prepared a patch in the event that others might
|
||||
find it useful as well.
|
||||
|
||||
Thanks and keep up the good work.
|
||||
|
||||
--Bob
|
||||
|
||||
11
contrib/try-all-ns/README-2.47
Normal file
11
contrib/try-all-ns/README-2.47
Normal file
@@ -0,0 +1,11 @@
|
||||
A remake of patch Bob Carroll had posted to dnsmasq,
|
||||
now compatible with version 2.47. Hopefully he doesn't
|
||||
mind (sending a copy of this mail to him too).
|
||||
|
||||
Maybe the patch in question is not acceptable
|
||||
as it doesn't add new switch, rather it binds itself to "strict-order".
|
||||
|
||||
What it does is: if you have strict-order in the
|
||||
dnsmasq config file and query a domain that would result
|
||||
in NXDOMAIN, it iterates the whole given nameserver list
|
||||
until the last one says NXDOMAIN.
|
||||
10
contrib/try-all-ns/README-2.78
Normal file
10
contrib/try-all-ns/README-2.78
Normal file
@@ -0,0 +1,10 @@
|
||||
Hi,
|
||||
I updated the try-all-ns patch to work with the latest version of git. Ended up implementing it on top of master, 2.78test2-7-g63437ff. As that specific if-clause has been changed in the last few commits, it's not compatible for 2.77, sadly.
|
||||
|
||||
Find the patch attached.
|
||||
|
||||
Regards,
|
||||
|
||||
Rasmus Ahlberg
|
||||
Software Developer, R&D
|
||||
Electrolux Small Appliances
|
||||
61
contrib/try-all-ns/dnsmasq-2.35-try-all-ns.patch
Normal file
61
contrib/try-all-ns/dnsmasq-2.35-try-all-ns.patch
Normal file
@@ -0,0 +1,61 @@
|
||||
diff -Nau dnsmasq-2.35/src/dnsmasq.h dnsmasq/src/dnsmasq.h
|
||||
--- dnsmasq-2.35/src/dnsmasq.h 2006-10-18 16:24:50.000000000 -0400
|
||||
+++ dnsmasq/src/dnsmasq.h 2006-11-16 22:06:31.000000000 -0500
|
||||
@@ -112,6 +112,7 @@
|
||||
#define OPT_NO_PING 2097152
|
||||
#define OPT_LEASE_RO 4194304
|
||||
#define OPT_RELOAD 8388608
|
||||
+#define OPT_TRY_ALL_NS 16777216
|
||||
|
||||
struct all_addr {
|
||||
union {
|
||||
diff -Nau dnsmasq-2.35/src/forward.c dnsmasq/src/forward.c
|
||||
--- dnsmasq-2.35/src/forward.c 2006-10-18 16:24:50.000000000 -0400
|
||||
+++ dnsmasq/src/forward.c 2006-11-16 22:08:19.000000000 -0500
|
||||
@@ -445,6 +445,10 @@
|
||||
{
|
||||
struct server *server = forward->sentto;
|
||||
|
||||
+ // If strict-order and try-all-ns are set, treat NXDOMAIN as a failed request
|
||||
+ if( (daemon->options & OPT_ORDER) && (daemon->options && OPT_TRY_ALL_NS)
|
||||
+ && header->rcode == NXDOMAIN ) header->rcode = SERVFAIL;
|
||||
+
|
||||
if ((header->rcode == SERVFAIL || header->rcode == REFUSED) && forward->forwardall == 0)
|
||||
/* for broken servers, attempt to send to another one. */
|
||||
{
|
||||
diff -Nau dnsmasq-2.35/src/option.c dnsmasq/src/option.c
|
||||
--- dnsmasq-2.35/src/option.c 2006-10-18 16:24:50.000000000 -0400
|
||||
+++ dnsmasq/src/option.c 2006-11-16 22:10:36.000000000 -0500
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
/* options which don't have a one-char version */
|
||||
#define LOPT_RELOAD 256
|
||||
-
|
||||
+#define LOPT_TRY_ALL_NS 257
|
||||
|
||||
#ifdef HAVE_GETOPT_LONG
|
||||
static const struct option opts[] =
|
||||
@@ -102,6 +102,7 @@
|
||||
{"leasefile-ro", 0, 0, '9'},
|
||||
{"dns-forward-max", 1, 0, '0'},
|
||||
{"clear-on-reload", 0, 0, LOPT_RELOAD },
|
||||
+ {"try-all-ns", 0, 0, LOPT_TRY_ALL_NS },
|
||||
{ NULL, 0, 0, 0 }
|
||||
};
|
||||
|
||||
@@ -134,6 +135,7 @@
|
||||
{ '5', OPT_NO_PING },
|
||||
{ '9', OPT_LEASE_RO },
|
||||
{ LOPT_RELOAD, OPT_RELOAD },
|
||||
+ { LOPT_TRY_ALL_NS,OPT_TRY_ALL_NS },
|
||||
{ 'v', 0},
|
||||
{ 'w', 0},
|
||||
{ 0, 0 }
|
||||
@@ -208,6 +210,7 @@
|
||||
{ "-9, --leasefile-ro", gettext_noop("Read leases at startup, but never write the lease file."), NULL },
|
||||
{ "-0, --dns-forward-max=<queries>", gettext_noop("Maximum number of concurrent DNS queries. (defaults to %s)"), "!" },
|
||||
{ " --clear-on-reload", gettext_noop("Clear DNS cache when reloading %s."), RESOLVFILE },
|
||||
+ { " --try-all-ns", gettext_noop("Try all name servers in tandem on NXDOMAIN replies (use with strict-order)."), NULL },
|
||||
{ NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
17
contrib/try-all-ns/dnsmasq-2.47_no_nxdomain_until_end.patch
Normal file
17
contrib/try-all-ns/dnsmasq-2.47_no_nxdomain_until_end.patch
Normal file
@@ -0,0 +1,17 @@
|
||||
diff -ur dnsmasq-2.47/src/forward.c dnsmasq-2.47-patched/src/forward.c
|
||||
--- dnsmasq-2.47/src/forward.c 2009-02-01 17:59:48.000000000 +0200
|
||||
+++ dnsmasq-2.47-patched/src/forward.c 2009-03-18 19:10:22.000000000 +0200
|
||||
@@ -488,9 +488,12 @@
|
||||
return;
|
||||
|
||||
server = forward->sentto;
|
||||
+
|
||||
+ if ( (header->rcode == NXDOMAIN) && ((daemon->options & OPT_ORDER) != 0) && (server->next != NULL) )
|
||||
+ header->rcode = SERVFAIL;
|
||||
|
||||
if ((header->rcode == SERVFAIL || header->rcode == REFUSED) &&
|
||||
- !(daemon->options & OPT_ORDER) &&
|
||||
+ ((daemon->options & OPT_ORDER) != 0) &&
|
||||
forward->forwardall == 0)
|
||||
/* for broken servers, attempt to send to another one. */
|
||||
{
|
||||
29
contrib/try-all-ns/dnsmasq-2.68-try-all-ns
Normal file
29
contrib/try-all-ns/dnsmasq-2.68-try-all-ns
Normal file
@@ -0,0 +1,29 @@
|
||||
From: Jesse Glick <jglick@cloudbees.com>
|
||||
To: dnsmasq-discuss@lists.thekelleys.org.uk
|
||||
Subject: Re: [Dnsmasq-discuss] Ability to delegate to one server but fall
|
||||
back to another after NXDOMAIN?
|
||||
|
||||
|
||||
On Wed, Jan 15, 2014 at 12:30 PM, Simon Kelley <simon@thekelleys.org.uk> wrote:
|
||||
> > There's a (very old) patch in contrib/try-all-ns that would make a starting point
|
||||
This does not apply against trunk, so I tried to rework it. The
|
||||
following appears to do what I expect:
|
||||
|
||||
diff --git a/src/forward.c b/src/forward.c
|
||||
index 8167229..76070b5 100644
|
||||
--- a/src/forward.c
|
||||
+++ b/src/forward.c
|
||||
@@ -610,7 +610,11 @@ void reply_query(int fd, int family, time_t now)
|
||||
|
||||
if ((RCODE(header) == SERVFAIL || RCODE(header) == REFUSED) &&
|
||||
!option_bool(OPT_ORDER) &&
|
||||
- forward->forwardall == 0)
|
||||
+ forward->forwardall == 0 ||
|
||||
+ /* try each in turn */
|
||||
+ RCODE(header) == NXDOMAIN &&
|
||||
+ option_bool(OPT_ORDER) &&
|
||||
+ server->next != NULL)
|
||||
/* for broken servers, attempt to send to another one. */
|
||||
{
|
||||
unsigned char *pheader;
|
||||
|
||||
20
contrib/try-all-ns/dnsmasq-2.78xx-try-all-ns.patch
Normal file
20
contrib/try-all-ns/dnsmasq-2.78xx-try-all-ns.patch
Normal file
@@ -0,0 +1,20 @@
|
||||
diff --git a/src/forward.c b/src/forward.c
|
||||
index e3fa94b..ecf3b98 100644
|
||||
--- a/src/forward.c
|
||||
+++ b/src/forward.c
|
||||
@@ -789,9 +789,12 @@ void reply_query(int fd, int family, time_t now)
|
||||
|
||||
/* Note: if we send extra options in the EDNS0 header, we can't recreate
|
||||
the query from the reply. */
|
||||
- if (RCODE(header) == REFUSED &&
|
||||
- forward->forwardall == 0 &&
|
||||
- !(forward->flags & FREC_HAS_EXTRADATA))
|
||||
+ if ((RCODE(header) == REFUSED &&
|
||||
+ forward->forwardall == 0 &&
|
||||
+ !(forward->flags & FREC_HAS_EXTRADATA)) ||
|
||||
+ /* If strict-order is set, try next server on NXDOMAIN reply */
|
||||
+ (RCODE(header) == NXDOMAIN && option_bool(OPT_ORDER) &&
|
||||
+ server->next != NULL))
|
||||
/* for broken servers, attempt to send to another one. */
|
||||
{
|
||||
unsigned char *pheader;
|
||||
54
contrib/webmin/README
Normal file
54
contrib/webmin/README
Normal file
@@ -0,0 +1,54 @@
|
||||
|
||||
This is the README for the Dnsmasq webmin module.
|
||||
|
||||
Problems:
|
||||
|
||||
1) There's only basic error checking - if you enter some bad
|
||||
addresses or names, they will go straight into the config file
|
||||
although we do check for things like IP addresses being of
|
||||
the correct form (no letters, 4 groups of up to 3 digits
|
||||
separated by dots etc). One thing that ISN'T CHECKED FOR is
|
||||
that IP dotted quads are all numbers < 256. Another is that
|
||||
netmasks are logical (you could enter a netmask of 255.0.255.0
|
||||
for example). Essentially, if it'll pass the config file
|
||||
regex scanner (and the above examples will), it won't be
|
||||
flagged as "bad" even if it is a big no-no for dnsmasq itself.
|
||||
|
||||
2) Code is ugly and a kludge - I ain't a programmer! There are probably
|
||||
a lot of things that could be done to tidy up the code - eg,
|
||||
it probably wouldn't hurt to move some common stuff into the lib file.
|
||||
|
||||
3) I've used the %text hash and written an english lang file, but
|
||||
I am mono-lingual so no other language support as yet.
|
||||
|
||||
4) for reasons unknown to me, the icon does not appear properly
|
||||
on the servers page of webmin (at least it doesn't for me!)
|
||||
|
||||
5) icons have been shamelessly stolen from the ipfilter module,
|
||||
specifically the up and down arrows.
|
||||
|
||||
6) if you delete an item, the config file will contain
|
||||
an otherwise empty, but commented line. This means that if
|
||||
you add some new stuff, then delete it, the config file
|
||||
will have a number of lines at the end that are just comments.
|
||||
Therefore, the config file could possibly grow quite large.
|
||||
|
||||
7) NO INCLUDE FILES!
|
||||
if you use an include file, it'll be flagged as an error.
|
||||
OK if the include file line is commented out though.
|
||||
|
||||
8) deprecated lines not supported (eg user and group) - they
|
||||
may produce an error! (user and group don't, but you can't change
|
||||
them)
|
||||
|
||||
IOW, it works, it's just not very elegant and not very robust.
|
||||
|
||||
Hope you find it useful though - I do, as I prevents me having to ever
|
||||
wade through the config file and man pages again.
|
||||
|
||||
If you modify it, or add a language file, and you have a spare moment,
|
||||
please e-mail me - I won't be upset at all if you fix my poor coding!
|
||||
(rather the opposite - I'd be pleased someone found it useful)
|
||||
|
||||
Cheers,
|
||||
Neil Fisher <neil@magnecor.com.au>
|
||||
BIN
contrib/webmin/dnsmasq.wbm
Normal file
BIN
contrib/webmin/dnsmasq.wbm
Normal file
Binary file not shown.
81
contrib/wrt/README
Normal file
81
contrib/wrt/README
Normal file
@@ -0,0 +1,81 @@
|
||||
This script can be used to implement persistent leases on openWRT, DD-WRT
|
||||
etc. Persistent leases are good: if the lease database is lost on a
|
||||
reboot, then it will eventually be restored as hosts renew their
|
||||
leases. Until a host renews (which may take hours/days) it will
|
||||
not exist in the DNS if dnsmasq's DDNS function is in use.
|
||||
|
||||
*WRT systems remount all non-volatile filesystems read-only after boot,
|
||||
so the normal leasefile will not work. They do, however have NV
|
||||
storage, accessed with the nvram command:
|
||||
|
||||
/usr/lib # nvram
|
||||
usage: nvram [get name] [set name=value] [unset name] [show]
|
||||
|
||||
The principle is that leases are kept in NV variable with data
|
||||
corresponding to the line in a leasefile:
|
||||
|
||||
dnsmasq_lease_192.168.1.56=3600 00:41:4a:05:80:74 192.168.1.56 * *
|
||||
|
||||
By giving dnsmasq the leasefile-ro command, it no longer creates or writes a
|
||||
leasefile; responsibility for maintaining the lease database transfers
|
||||
to the lease change script. At startup, in leasefile-ro mode,
|
||||
dnsmasq will run
|
||||
|
||||
"<lease_change_script> init"
|
||||
|
||||
and read whatever that command spits out, expecting it to
|
||||
be in dnsmasq leasefile format.
|
||||
|
||||
So the lease change script, given "init" as argv[1] will
|
||||
suck existing leases out of the NVRAM and emit them from
|
||||
stdout in the correct format.
|
||||
|
||||
The second part of the problem is keeping the NVRAM up-to-date: this
|
||||
is done by the lease-change script which dnsmasq runs when a lease is
|
||||
updated. When it is called with argv[1] as "old", "add", or "del"
|
||||
it updates the relevant nvram entry.
|
||||
|
||||
So, dnsmasq should be run as :
|
||||
|
||||
dnsmasq --leasefile-ro --dhcp-script=/path/to/lease_update.sh
|
||||
|
||||
or the same flags added to /etc/dnsmasq.conf
|
||||
|
||||
|
||||
|
||||
Notes:
|
||||
|
||||
This needs dnsmasq-2.33 or later to work.
|
||||
|
||||
This technique will work with, or without, compilation with
|
||||
HAVE_BROKEN_RTC. Compiling with HAVE_BROKEN_RTC is
|
||||
_highly_recommended_ for this application since is avoids problems
|
||||
with the system clock being warped by NTP, and it vastly reduces the
|
||||
number of writes to the NVRAM. With HAVE_BROKEN_RTC, NVRAM is updated
|
||||
only when a lease is created or destroyed; without it, a write occurs
|
||||
every time a lease is renewed.
|
||||
|
||||
It probably makes sense to restrict the number of active DHCP leases
|
||||
to an appropriate number using dhcp-lease-max. On a new DD_WRT system,
|
||||
there are about 10K bytes free in the NVRAM. Each lease record is
|
||||
about 100 bytes, so restricting the number of leases to 50 will limit
|
||||
use to half that. (The default limit in the distributed source is 150)
|
||||
|
||||
Any UI script which reads the dnsmasq leasefile will have to be
|
||||
amended, probably by changing it to read the output of
|
||||
`lease_update init` instead.
|
||||
|
||||
|
||||
Thanks:
|
||||
|
||||
To Steve Horbachuk for checks on the script and debugging beyond the
|
||||
call of duty.
|
||||
|
||||
|
||||
Simon Kelley
|
||||
Fri Jul 28 11:51:13 BST 2006
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
54
contrib/wrt/lease_update.sh
Executable file
54
contrib/wrt/lease_update.sh
Executable file
@@ -0,0 +1,54 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Copyright (c) 2006 Simon Kelley
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; version 2 dated June, 1991.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
|
||||
# if $1 is add del or old, this is a dnsmasq-called lease-change
|
||||
# script, update the nvram database. if $1 is init, emit a
|
||||
# dnsmasq-format lease file to stdout representing the current state of the
|
||||
# database, this is called by dnsmasq at startup.
|
||||
|
||||
NVRAM=/usr/sbin/nvram
|
||||
PREFIX=dnsmasq_lease_
|
||||
|
||||
# Arguments.
|
||||
# $1 is action (add, del, old)
|
||||
# $2 is MAC
|
||||
# $3 is address
|
||||
# $4 is hostname (optional, may be unset)
|
||||
|
||||
# env.
|
||||
# DNSMASQ_LEASE_LENGTH or DNSMASQ_LEASE_EXPIRES (which depends on HAVE_BROKEN_RTC)
|
||||
# DNSMASQ_CLIENT_ID (optional, may be unset)
|
||||
|
||||
# File.
|
||||
# length|expires MAC addr hostname|* CLID|*
|
||||
|
||||
# Primary key is address.
|
||||
|
||||
if [ ${1} = init ] ; then
|
||||
${NVRAM} show | sed -n -e "/^${PREFIX}.*/ s/^.*=//p"
|
||||
else
|
||||
if [ ${1} = del ] ; then
|
||||
${NVRAM} unset ${PREFIX}${3}
|
||||
fi
|
||||
|
||||
if [ ${1} = old ] || [ ${1} = add ] ; then
|
||||
${NVRAM} set ${PREFIX}${3}="${DNSMASQ_LEASE_LENGTH:-}${DNSMASQ_LEASE_EXPIRES:-} ${2} ${3} ${4:-*} ${DNSMASQ_CLIENT_ID:-*}"
|
||||
fi
|
||||
${NVRAM} commit
|
||||
fi
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
307
dbus/DBus-interface
Normal file
307
dbus/DBus-interface
Normal file
@@ -0,0 +1,307 @@
|
||||
DBus support must be enabled at compile-time and run-time. Ensure
|
||||
that src/config.h contains the line
|
||||
|
||||
#define HAVE_DBUS.
|
||||
|
||||
and that /etc/dnsmasq.conf contains the line
|
||||
|
||||
enable-dbus
|
||||
|
||||
Because dnsmasq can operate stand-alone from the DBus, and may need to provide
|
||||
service before the dbus daemon is available, it will continue to run
|
||||
if the DBus connection is not available at startup. The DBus will be polled
|
||||
every 250ms until a connection is established. Start of polling and final
|
||||
connection establishment are both logged. When dnsmasq establishes a
|
||||
connection to the dbus, it sends the signal "Up". Anything controlling
|
||||
the server settings in dnsmasq should re-invoke the SetServers method
|
||||
(q.v.) when it sees this signal. This allows dnsmasq to be restarted
|
||||
and avoids startup races with the provider of nameserver information.
|
||||
|
||||
|
||||
Dnsmasq provides one service on the DBus: uk.org.thekelleys.dnsmasq
|
||||
and a single object: /uk/org/thekelleys/dnsmasq
|
||||
The name of the service may be changed by giving an argument to --enable-dbus.
|
||||
|
||||
1. METHODS
|
||||
----------
|
||||
|
||||
Methods are of the form
|
||||
|
||||
uk.org.thekelleys.<method>
|
||||
|
||||
Available methods are:
|
||||
|
||||
GetVersion
|
||||
----------
|
||||
Returns a string containing the version of dnsmasq running.
|
||||
|
||||
ClearCache
|
||||
----------
|
||||
Returns nothing. Clears the domain name cache and re-reads
|
||||
/etc/hosts. The same as sending dnsmasq a HUP signal.
|
||||
|
||||
SetFilterWin2KOption
|
||||
--------------------
|
||||
Takes boolean, sets or resets the --filterwin2k option.
|
||||
|
||||
SetFilterA
|
||||
------------------------
|
||||
Takes boolean, sets or resets the --filter-A option.
|
||||
|
||||
SetFilterAAAA
|
||||
------------------------
|
||||
Takes boolean, sets or resets the --filter-AAAA option.
|
||||
|
||||
SetBogusPrivOption
|
||||
------------------
|
||||
Takes boolean, sets or resets the --bogus-priv option.
|
||||
|
||||
SetLocaliseQueriesOption
|
||||
------------------------
|
||||
Takes boolean, sets or resets the --localise-queries option.
|
||||
|
||||
SetServers
|
||||
----------
|
||||
Returns nothing. Takes a set of arguments representing the new
|
||||
upstream DNS servers to be used by dnsmasq. IPv4 addresses are
|
||||
represented as a UINT32 (in network byte order) and IPv6 addresses
|
||||
are represented as sixteen BYTEs (since there is no UINT128 type).
|
||||
Each server address may be followed by one or more STRINGS, which are
|
||||
the domains for which the preceding server should be used.
|
||||
|
||||
Examples.
|
||||
|
||||
UINT32: <address1>
|
||||
UNIT32: <address2>
|
||||
|
||||
is equivalent to
|
||||
|
||||
--server=<address1> --server=<address2>
|
||||
|
||||
|
||||
UINT32 <address1>
|
||||
UINT32 <address2>
|
||||
STRING "somedomain.com"
|
||||
|
||||
is equivalent to
|
||||
|
||||
--server=<address1> --server=/somedomain.com/<address2>
|
||||
|
||||
UINT32 <address1>
|
||||
UINT32 <address2>
|
||||
STRING "somedomain.com"
|
||||
UINT32 <address3>
|
||||
STRING "anotherdomain.com"
|
||||
STRING "thirddomain.com"
|
||||
|
||||
is equivalent to
|
||||
|
||||
--server=<address1>
|
||||
--server=/somedomain.com/<address2>
|
||||
--server=/anotherdomain.com/thirddomain.com/<address3>
|
||||
|
||||
Am IPv4 address of 0.0.0.0 is interpreted as "no address, local only",
|
||||
so
|
||||
|
||||
UINT32: <0.0.0.0>
|
||||
STRING "local.domain"
|
||||
|
||||
is equivalent to
|
||||
|
||||
--local=/local.domain/
|
||||
|
||||
|
||||
Each call to SetServers completely replaces the set of servers
|
||||
specified by via the DBus, but it leaves any servers specified via the
|
||||
command line or /etc/dnsmasq.conf or /etc/resolv.conf alone.
|
||||
|
||||
SetServersEx
|
||||
------------
|
||||
|
||||
This function is more flexible and the SetServers function, in that it can
|
||||
handle address scoping, port numbers, and is easier for clients to use.
|
||||
|
||||
Returns nothing. Takes a set of arguments representing the new
|
||||
upstream DNS servers to be used by dnsmasq. All addresses (both IPv4 and IPv6)
|
||||
are represented as STRINGS. Each server address may be followed by one or more
|
||||
STRINGS, which are the domains for which the preceding server should be used.
|
||||
|
||||
This function takes an array of STRING arrays, where each inner array represents
|
||||
a set of DNS servers and domains for which those servers may be used. Each
|
||||
string represents a list of upstream DNS servers first, and domains second.
|
||||
Mixing of domains and servers within a the string array is not allowed.
|
||||
|
||||
Examples.
|
||||
|
||||
[
|
||||
["1.2.3.4", "foobar.com"],
|
||||
["1003:1234:abcd::1%eth0", "eng.mycorp.com", "lab.mycorp.com"]
|
||||
]
|
||||
|
||||
is equivalent to
|
||||
|
||||
--server=/foobar.com/1.2.3.4 \
|
||||
--server=/eng.mycorp.com/lab.mycorp.com/1003:1234:abcd::1%eth0
|
||||
|
||||
An IPv4 address of 0.0.0.0 is interpreted as "no address, local only",
|
||||
so
|
||||
|
||||
[ ["0.0.0.0", "local.domain"] ]
|
||||
|
||||
is equivalent to
|
||||
|
||||
--local=/local.domain/
|
||||
|
||||
|
||||
Each call to SetServersEx completely replaces the set of servers
|
||||
specified by via the DBus, but it leaves any servers specified via the
|
||||
command line or /etc/dnsmasq.conf or /etc/resolv.conf alone.
|
||||
|
||||
|
||||
SetDomainServers
|
||||
----------------
|
||||
|
||||
Yes another variation for setting DNS servers, with the capability of
|
||||
SetServersEx, but without using arrays of arrays, which are not
|
||||
sendable with dbus-send. The arguments are an array of strings which
|
||||
are identical to the equivalent arguments --server, so the example
|
||||
for SetServersEx is represented as
|
||||
|
||||
[
|
||||
"/foobar.com/1.2.3.4"
|
||||
"/eng.mycorp.com/lab.mycorp.com/1003:1234:abcd::1%eth0"
|
||||
]
|
||||
|
||||
GetLoopServers
|
||||
--------------
|
||||
|
||||
(Only available if dnsmasq compiled with HAVE_LOOP)
|
||||
|
||||
Return an array of strings, each string is the IP address of an upstream
|
||||
server which has been found to loop queries back to this dnsmasq instance, and
|
||||
it therefore not being used.
|
||||
|
||||
AddDhcpLease
|
||||
------------
|
||||
|
||||
Returns nothing. Adds or updates a DHCP or DHCPv6 lease to the internal lease
|
||||
database, as if a client requested and obtained a lease.
|
||||
|
||||
If a lease for the IPv4 or IPv6 address already exist, it is overwritten.
|
||||
|
||||
Note that this function will trigger the DhcpLeaseAdded or DhcpLeaseUpdated
|
||||
D-Bus signal and will run the configured DHCP lease script accordingly.
|
||||
|
||||
This function takes many arguments which are the lease parameters:
|
||||
- A string with the textual representation of the IPv4 or IPv6 address of the
|
||||
client.
|
||||
|
||||
Examples:
|
||||
"192.168.1.115"
|
||||
"1003:1234:abcd::1%eth0"
|
||||
"2001:db8:abcd::1"
|
||||
|
||||
- A string representing the hardware address of the client, using the same
|
||||
format as the one used in the lease database.
|
||||
|
||||
Examples:
|
||||
|
||||
"00:23:45:67:89:ab"
|
||||
"06-00:20:e0:3b:13:af" (token ring)
|
||||
|
||||
- The hostname of the client, as an array of bytes (so there is no problem
|
||||
with non-ASCII character encoding). May be empty.
|
||||
|
||||
Example (for "hostname.or.fqdn"):
|
||||
[104, 111, 115, 116, 110, 97, 109, 101, 46, 111, 114, 46, 102, 113, 100, 110]
|
||||
|
||||
- The client identifier (IPv4) or DUID (IPv6) as an array of bytes. May be
|
||||
empty.
|
||||
|
||||
Examples:
|
||||
|
||||
DHCPv6 DUID:
|
||||
[0, 3, 0, 1, 0, 35, 69, 103, 137, 171]
|
||||
DHCPv4 client identifier:
|
||||
[255, 12, 34, 56, 78, 0, 1, 0, 1, 29, 9, 99, 190, 35, 69, 103, 137, 171]
|
||||
|
||||
- The duration of the lease, in seconds. If the lease is updated, then
|
||||
the duration replaces the previous duration.
|
||||
|
||||
Example:
|
||||
|
||||
7200
|
||||
|
||||
- The IAID (Identity association identifier) of the DHCPv6 lease, as a network
|
||||
byte-order unsigned integer. For DHCPv4 leases, this must be set to 0.
|
||||
|
||||
Example (for IPv6):
|
||||
|
||||
203569230
|
||||
|
||||
- A boolean which, if true, indicates that the DHCPv6 lease is for a temporary
|
||||
address (IA_TA). If false, the DHCPv6 lease is for a non-temporary address
|
||||
(IA_NA). For DHCPv4 leases, this must be set to false.
|
||||
|
||||
RemoveDhcpLease
|
||||
---------------
|
||||
|
||||
Returns nothing. Removes a DHCP or DHCPv6 lease to the internal lease
|
||||
database, as if a client sent a release message to abandon a lease.
|
||||
|
||||
This function takes only one parameter: the text representation of the
|
||||
IPv4 or IPv6 address of the lease to remove.
|
||||
|
||||
Note that this function will trigger the DhcpLeaseRemoved signal and the
|
||||
configured DHCP lease script will be run with the "del" action.
|
||||
|
||||
GetMetrics
|
||||
----------
|
||||
|
||||
Returns an array with various metrics for DNS and DHCP.
|
||||
|
||||
GetServerMetrics
|
||||
----------------
|
||||
|
||||
Returns per-DNS-server metrics.
|
||||
|
||||
ClearMetrics
|
||||
------------
|
||||
|
||||
Clear call metric counters, global and per-server.
|
||||
|
||||
2. SIGNALS
|
||||
----------
|
||||
|
||||
If dnsmasq's DHCP server is active, it will send signals over DBUS whenever
|
||||
the DHCP lease database changes. Think of these signals as transactions on
|
||||
a database with the IP address acting as the primary key.
|
||||
|
||||
Signals are of the form:
|
||||
|
||||
uk.org.thekelleys.<signal>
|
||||
|
||||
and their parameters are:
|
||||
|
||||
STRING "192.168.1.115"
|
||||
STRING "01:23:45:67:89:ab"
|
||||
STRING "hostname.or.fqdn"
|
||||
|
||||
|
||||
Available signals are:
|
||||
|
||||
DhcpLeaseAdded
|
||||
---------------
|
||||
|
||||
This signal is emitted when a DHCP lease for a given IP address is created.
|
||||
|
||||
DhcpLeaseDeleted
|
||||
----------------
|
||||
|
||||
This signal is emitted when a DHCP lease for a given IP address is deleted.
|
||||
|
||||
DhcpLeaseUpdated
|
||||
----------------
|
||||
|
||||
This signal is emitted when a DHCP lease for a given IP address is updated.
|
||||
|
||||
14
dbus/dnsmasq.conf
Normal file
14
dbus/dnsmasq.conf
Normal file
@@ -0,0 +1,14 @@
|
||||
<!DOCTYPE busconfig PUBLIC
|
||||
"-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
|
||||
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
|
||||
<busconfig>
|
||||
<policy user="root">
|
||||
<allow own="uk.org.thekelleys.dnsmasq"/>
|
||||
<allow send_destination="uk.org.thekelleys.dnsmasq"/>
|
||||
</policy>
|
||||
<policy context="default">
|
||||
<deny own="uk.org.thekelleys.dnsmasq"/>
|
||||
<deny send_destination="uk.org.thekelleys.dnsmasq"/>
|
||||
</policy>
|
||||
</busconfig>
|
||||
|
||||
133
dnsmasq-rh.spec
133
dnsmasq-rh.spec
@@ -1,133 +0,0 @@
|
||||
###############################################################################
|
||||
#
|
||||
# General mumbojumbo
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
Name: dnsmasq
|
||||
Version: 2.30
|
||||
Release: 1
|
||||
License: GPL
|
||||
Group: System Environment/Daemons
|
||||
Vendor: Simon Kelley
|
||||
Packager: Simon Kelley
|
||||
Distribution: Red Hat Linux
|
||||
URL: http://www.thekelleys.org.uk/dnsmasq
|
||||
Source0: %{name}-%{version}.tar.gz
|
||||
Requires: chkconfig
|
||||
BuildRoot: /var/tmp/%{name}-%{version}
|
||||
Summary: A lightweight caching nameserver
|
||||
|
||||
%description
|
||||
Dnsmasq is lightweight, easy to configure DNS forwarder and DHCP server. It
|
||||
is designed to provide DNS and, optionally, DHCP, to a small network. It can
|
||||
serve the names of local machines which are not in the global DNS. The DHCP
|
||||
server integrates with the DNS server and allows machines with DHCP-allocated
|
||||
addresses to appear in the DNS with names configured either in each host or
|
||||
in a central configuration file. Dnsmasq supports static and dynamic DHCP
|
||||
leases and BOOTP for network booting of diskless machines.
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# Build
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
%prep
|
||||
%setup -q
|
||||
%build
|
||||
make all-i18n PREFIX=/usr
|
||||
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# Install
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
%install
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
mkdir -p -m 755 $RPM_BUILD_ROOT/usr/sbin
|
||||
mkdir -p -m 755 $RPM_BUILD_ROOT/etc/rc.d/init.d
|
||||
mkdir -p -m 755 $RPM_BUILD_ROOT/usr/share/man/man8
|
||||
|
||||
cp rpm/dnsmasq.rh $RPM_BUILD_ROOT/etc/rc.d/init.d/dnsmasq
|
||||
make install-i18n DESTDIR=$RPM_BUILD_ROOT PREFIX=/usr
|
||||
strip $RPM_BUILD_ROOT/usr/sbin/dnsmasq
|
||||
cp src/dnsmasq $RPM_BUILD_ROOT/usr/sbin
|
||||
cp dnsmasq.conf.example $RPM_BUILD_ROOT/etc/dnsmasq.conf
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# Clean up
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# Post-install scriptlet
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
%post
|
||||
/sbin/chkconfig --add dnsmasq
|
||||
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# Pre-uninstall scriptlet
|
||||
#
|
||||
# If there's a time when your package needs to have one last look around before
|
||||
# the user erases it, the place to do it is in the %preun script. Anything that
|
||||
# a package needs to do immediately prior to RPM taking any action to erase the
|
||||
# package, can be done here.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
%preun
|
||||
if [ $1 = 0 ]; then # execute this only if we are NOT doing an upgrade
|
||||
service dnsmasq stop >/dev/null 2>&1
|
||||
/sbin/chkconfig --del dnsmasq
|
||||
fi
|
||||
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# Post-uninstall scriptlet
|
||||
#
|
||||
# The %postun script executes after the package has been removed. It is the
|
||||
# last chance for a package to clean up after itself.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
%postun
|
||||
if [ "$1" -ge "1" ]; then
|
||||
service dnsmasq restart >/dev/null 2>&1
|
||||
fi
|
||||
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# File list
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
%files
|
||||
%defattr(-,root,root)
|
||||
%doc CHANGELOG COPYING FAQ doc.html setup.html UPGRADING_to_2.0
|
||||
%config /etc/rc.d/init.d/dnsmasq
|
||||
%config /etc/dnsmasq.conf
|
||||
%attr(0755,root,root) /etc/rc.d/init.d/dnsmasq
|
||||
%attr(0664,root,root) /etc/dnsmasq.conf
|
||||
%attr(0755,root,root) /usr/sbin/dnsmasq
|
||||
#%attr(0644,root,root) /usr/share/man/*/man8/dnsmasq*
|
||||
%attr(0644,root,root) /usr/share/man/man8/dnsmasq*
|
||||
%attr(0644,root,root) /usr/share/locale/*/LC_MESSAGES/*
|
||||
|
||||
@@ -1,111 +0,0 @@
|
||||
###############################################################################
|
||||
#
|
||||
# General
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
Name: dnsmasq
|
||||
Version: 2.30
|
||||
Release: 1
|
||||
Copyright: GPL
|
||||
Group: Productivity/Networking/DNS/Servers
|
||||
Vendor: Simon Kelley
|
||||
Packager: Simon Kelley
|
||||
URL: http://www.thekelleys.org.uk/dnsmasq
|
||||
Provides: dns_daemon
|
||||
Conflicts: bind bind8 bind9
|
||||
PreReq: %fillup_prereq %insserv_prereq
|
||||
Autoreqprov: on
|
||||
Source0: %{name}-%{version}.tar.bz2
|
||||
BuildRoot: /var/tmp/%{name}-%{version}
|
||||
Summary: A lightweight caching nameserver
|
||||
|
||||
%description
|
||||
Dnsmasq is lightweight, easy to configure DNS forwarder and DHCP server. It
|
||||
is designed to provide DNS and, optionally, DHCP, to a small network. It can
|
||||
serve the names of local machines which are not in the global DNS. The DHCP
|
||||
server integrates with the DNS server and allows machines with DHCP-allocated
|
||||
addresses to appear in the DNS with names configured either in each host or
|
||||
in a central configuration file. Dnsmasq supports static and dynamic DHCP
|
||||
leases and BOOTP for network booting of diskless machines.
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# Build
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
%prep
|
||||
%setup -q
|
||||
patch -p0 <rpm/%{name}-SuSE.patch
|
||||
|
||||
%build
|
||||
%{?suse_update_config:%{suse_update_config -f}}
|
||||
make all-i18n DESTDIR=$RPM_BUILD_ROOT PREFIX=/usr
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# Install
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
%install
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
mkdir -p ${RPM_BUILD_ROOT}/etc/init.d
|
||||
make install-i18n DESTDIR=$RPM_BUILD_ROOT PREFIX=/usr
|
||||
install -o root -g root -m 755 rpm/rc.dnsmasq-suse $RPM_BUILD_ROOT/etc/init.d/dnsmasq
|
||||
install -o root -g root -m 644 dnsmasq.conf.example $RPM_BUILD_ROOT/etc/dnsmasq.conf
|
||||
strip $RPM_BUILD_ROOT/usr/sbin/dnsmasq
|
||||
ln -sf ../../etc/init.d/dnsmasq $RPM_BUILD_ROOT/usr/sbin/rcdnsmasq
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# Clean up
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# Post-install scriptlet
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
%post
|
||||
%{fillup_and_insserv dnsmasq}
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# Post-uninstall scriptlet
|
||||
#
|
||||
# The %postun script executes after the package has been removed. It is the
|
||||
# last chance for a package to clean up after itself.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
%postun
|
||||
%{insserv_cleanup}
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# File list
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
%files
|
||||
%defattr(-,root,root)
|
||||
%doc CHANGELOG COPYING FAQ doc.html setup.html UPGRADING_to_2.0 rpm/README.susefirewall
|
||||
%doc contrib
|
||||
%config /etc/init.d/dnsmasq
|
||||
%config /etc/dnsmasq.conf
|
||||
/usr/sbin/rcdnsmasq
|
||||
/usr/sbin/dnsmasq
|
||||
/usr/share/locale/*/LC_MESSAGES/*
|
||||
%doc %{_mandir}/man8/dnsmasq.8.gz
|
||||
|
||||
|
||||
|
||||
@@ -4,22 +4,39 @@
|
||||
# as the long options legal on the command line. See
|
||||
# "/usr/sbin/dnsmasq --help" or "man 8 dnsmasq" for details.
|
||||
|
||||
# Listen on this specific port instead of the standard DNS port
|
||||
# (53). Setting this to zero completely disables DNS function,
|
||||
# leaving only DHCP and/or TFTP.
|
||||
#port=5353
|
||||
|
||||
# The following two options make you a better netizen, since they
|
||||
# tell dnsmasq to filter out queries which the public DNS cannot
|
||||
# answer, and which load the servers (especially the root servers)
|
||||
# uneccessarily. If you have a dial-on-demand link they also stop
|
||||
# these requests from bringing up the link uneccessarily.
|
||||
# unnecessarily. If you have a dial-on-demand link they also stop
|
||||
# these requests from bringing up the link unnecessarily.
|
||||
|
||||
# Never forward plain names (without a dot or domain part)
|
||||
domain-needed
|
||||
#domain-needed
|
||||
# Never forward addresses in the non-routed address spaces.
|
||||
bogus-priv
|
||||
#bogus-priv
|
||||
|
||||
# Uncomment these to enable DNSSEC validation and caching:
|
||||
# (Requires dnsmasq to be built with DNSSEC option.)
|
||||
#conf-file=%%PREFIX%%/share/dnsmasq/trust-anchors.conf
|
||||
#dnssec
|
||||
|
||||
# Replies which are not DNSSEC signed may be legitimate, because the domain
|
||||
# is unsigned, or may be forgeries. Setting this option tells dnsmasq to
|
||||
# check that an unsigned reply is OK, by finding a secure proof that a DS
|
||||
# record somewhere between the root and the domain does not exist.
|
||||
# The cost of setting this is that even queries in unsigned domains will need
|
||||
# one or more extra DNS queries to verify.
|
||||
#dnssec-check-unsigned
|
||||
|
||||
# Uncomment this to filter useless windows-originated DNS requests
|
||||
# which can trigger dial-on-demand links needlessly.
|
||||
# Note that (amongst other things) this blocks all SRV requests,
|
||||
# so don't use it if you use eg Kerberos.
|
||||
# so don't use it if you use eg Kerberos, SIP, XMMP or Google-talk.
|
||||
# This option only affects forwarding, SRV records originating for
|
||||
# dnsmasq (via srv-host= lines) are not suppressed by it.
|
||||
#filterwin2k
|
||||
@@ -37,7 +54,7 @@ bogus-priv
|
||||
|
||||
# If you don't want dnsmasq to read /etc/resolv.conf or any other
|
||||
# file, getting its servers from this file instead (see below), then
|
||||
# uncomment this
|
||||
# uncomment this.
|
||||
#no-resolv
|
||||
|
||||
# If you don't want dnsmasq to poll /etc/resolv.conf or other resolv
|
||||
@@ -48,14 +65,44 @@ bogus-priv
|
||||
# non-public domains.
|
||||
#server=/localnet/192.168.0.1
|
||||
|
||||
# Example of routing PTR queries to nameservers: this will send all
|
||||
# address->name queries for 192.168.3/24 to nameserver 10.1.2.3
|
||||
#server=/3.168.192.in-addr.arpa/10.1.2.3
|
||||
|
||||
# Add local-only domains here, queries in these domains are answered
|
||||
# from /etc/hosts or DHCP only.
|
||||
#local=/localnet/
|
||||
|
||||
# Add domains which you want to force to an IP address here.
|
||||
# The example below send any host in doubleclick.net to a local
|
||||
# webserver.
|
||||
#address=/doubleclick.net/127.0.0.1
|
||||
# The example below send any host in double-click.net to a local
|
||||
# web-server.
|
||||
#address=/double-click.net/127.0.0.1
|
||||
|
||||
# --address (and --server) work with IPv6 addresses too.
|
||||
#address=/www.thekelleys.org.uk/fe80::20d:60ff:fe36:f83
|
||||
|
||||
# Add the IPs of all queries to yahoo.com, google.com, and their
|
||||
# subdomains to the vpn and search ipsets:
|
||||
#ipset=/yahoo.com/google.com/vpn,search
|
||||
|
||||
# Add the IPs of all queries to yahoo.com, google.com, and their
|
||||
# subdomains to netfilters sets, which is equivalent to
|
||||
# 'nft add element ip test vpn { ... }; nft add element ip test search { ... }'
|
||||
#nftset=/yahoo.com/google.com/ip#test#vpn,ip#test#search
|
||||
|
||||
# Use netfilters sets for both IPv4 and IPv6:
|
||||
# This adds all addresses in *.yahoo.com to vpn4 and vpn6 for IPv4 and IPv6 addresses.
|
||||
#nftset=/yahoo.com/4#ip#test#vpn4
|
||||
#nftset=/yahoo.com/6#ip#test#vpn6
|
||||
|
||||
# You can control how dnsmasq talks to a server: this forces
|
||||
# queries to 10.1.2.3 to be routed via eth1
|
||||
# server=10.1.2.3@eth1
|
||||
|
||||
# and this sets the source (ie local) address used to talk to
|
||||
# 10.1.2.3 to 192.168.1.1 port 55 (there must be an interface with that
|
||||
# IP on the machine, obviously).
|
||||
# server=10.1.2.3@192.168.1.1#55
|
||||
|
||||
# If you want dnsmasq to change uid and gid to something other
|
||||
# than the default, edit the following lines.
|
||||
@@ -74,7 +121,7 @@ bogus-priv
|
||||
#listen-address=
|
||||
# If you want dnsmasq to provide only DNS service on an interface,
|
||||
# configure it as shown above, and then use the following line to
|
||||
# disable DHCP on it.
|
||||
# disable DHCP and TFTP on it.
|
||||
#no-dhcp-interface=
|
||||
|
||||
# On systems which support it, dnsmasq binds the wildcard address,
|
||||
@@ -106,6 +153,12 @@ bogus-priv
|
||||
# 3) Provides the domain part for "expand-hosts"
|
||||
#domain=thekelleys.org.uk
|
||||
|
||||
# Set a different domain for a particular subnet
|
||||
#domain=wireless.thekelleys.org.uk,192.168.2.0/24
|
||||
|
||||
# Same idea, but range rather then subnet
|
||||
#domain=reserved.thekelleys.org.uk,192.68.3.100,192.168.3.200
|
||||
|
||||
# Uncomment this to enable the integrated DHCP server, you need
|
||||
# to supply the range of addresses available for lease and optionally
|
||||
# a lease time. If you have more than one network, you will need to
|
||||
@@ -119,17 +172,68 @@ bogus-priv
|
||||
# don't need to worry about this.
|
||||
#dhcp-range=192.168.0.50,192.168.0.150,255.255.255.0,12h
|
||||
|
||||
# This is an example of a DHCP range with a network-id, so that
|
||||
# This is an example of a DHCP range which sets a tag, so that
|
||||
# some DHCP options may be set only for this network.
|
||||
#dhcp-range=red,192.168.0.50,192.168.0.150
|
||||
#dhcp-range=set:red,192.168.0.50,192.168.0.150
|
||||
|
||||
# Use this DHCP range only when the tag "green" is set.
|
||||
#dhcp-range=tag:green,192.168.0.50,192.168.0.150,12h
|
||||
|
||||
# Specify a subnet which can't be used for dynamic address allocation,
|
||||
# is available for hosts with matching --dhcp-host lines. Note that
|
||||
# dhcp-host declarations will be ignored unless there is a dhcp-range
|
||||
# of some type for the subnet in question.
|
||||
# In this case the netmask is implied (it comes from the network
|
||||
# configuration on the machine running dnsmasq) it is possible to give
|
||||
# an explicit netmask instead.
|
||||
#dhcp-range=192.168.0.0,static
|
||||
|
||||
# Enable DHCPv6. Note that the prefix-length does not need to be specified
|
||||
# and defaults to 64 if missing/
|
||||
#dhcp-range=1234::2, 1234::500, 64, 12h
|
||||
|
||||
# Do Router Advertisements, BUT NOT DHCP for this subnet.
|
||||
#dhcp-range=1234::, ra-only
|
||||
|
||||
# Do Router Advertisements, BUT NOT DHCP for this subnet, also try and
|
||||
# add names to the DNS for the IPv6 address of SLAAC-configured dual-stack
|
||||
# hosts. Use the DHCPv4 lease to derive the name, network segment and
|
||||
# MAC address and assume that the host will also have an
|
||||
# IPv6 address calculated using the SLAAC algorithm.
|
||||
#dhcp-range=1234::, ra-names
|
||||
|
||||
# Do Router Advertisements, BUT NOT DHCP for this subnet.
|
||||
# Set the lifetime to 46 hours. (Note: minimum lifetime is 2 hours.)
|
||||
#dhcp-range=1234::, ra-only, 48h
|
||||
|
||||
# Do DHCP and Router Advertisements for this subnet. Set the A bit in the RA
|
||||
# so that clients can use SLAAC addresses as well as DHCP ones.
|
||||
#dhcp-range=1234::2, 1234::500, slaac
|
||||
|
||||
# Do Router Advertisements and stateless DHCP for this subnet. Clients will
|
||||
# not get addresses from DHCP, but they will get other configuration information.
|
||||
# They will use SLAAC for addresses.
|
||||
#dhcp-range=1234::, ra-stateless
|
||||
|
||||
# Do stateless DHCP, SLAAC, and generate DNS names for SLAAC addresses
|
||||
# from DHCPv4 leases.
|
||||
#dhcp-range=1234::, ra-stateless, ra-names
|
||||
|
||||
# Do router advertisements for all subnets where we're doing DHCPv6
|
||||
# Unless overridden by ra-stateless, ra-names, et al, the router
|
||||
# advertisements will have the M and O bits set, so that the clients
|
||||
# get addresses and configuration from DHCPv6, and the A bit reset, so the
|
||||
# clients don't use SLAAC addresses.
|
||||
#enable-ra
|
||||
|
||||
# Supply parameters for specified hosts using DHCP. There are lots
|
||||
# of valid alternatives, so we will give examples of each. Note that
|
||||
# IP addresses DO NOT have to be in the range given above, they just
|
||||
# need to be on the same network. The order of the parameters in these
|
||||
# do not matter, it's permissble to give name,adddress and MAC in any order
|
||||
# do not matter, it's permissible to give name, address and MAC in any
|
||||
# order.
|
||||
|
||||
# Always allocate the host with ethernet address 11:22:33:44:55:66
|
||||
# Always allocate the host with Ethernet address 11:22:33:44:55:66
|
||||
# The IP address 192.168.0.60
|
||||
#dhcp-host=11:22:33:44:55:66,192.168.0.60
|
||||
|
||||
@@ -137,11 +241,19 @@ bogus-priv
|
||||
# 11:22:33:44:55:66 to be "fred"
|
||||
#dhcp-host=11:22:33:44:55:66,fred
|
||||
|
||||
# Always give the host with ethernet address 11:22:33:44:55:66
|
||||
# Always give the host with Ethernet address 11:22:33:44:55:66
|
||||
# the name fred and IP address 192.168.0.60 and lease time 45 minutes
|
||||
#dhcp-host=11:22:33:44:55:66,fred,192.168.0.60,45m
|
||||
|
||||
# Give the machine which says it's name is "bert" IP address
|
||||
# Give a host with Ethernet address 11:22:33:44:55:66 or
|
||||
# 12:34:56:78:90:12 the IP address 192.168.0.60. Dnsmasq will assume
|
||||
# that these two Ethernet interfaces will never be in use at the same
|
||||
# time, and give the IP address to the second, even if it is already
|
||||
# in use by the first. Useful for laptops with wired and wireless
|
||||
# addresses.
|
||||
#dhcp-host=11:22:33:44:55:66,12:34:56:78:90:12,192.168.0.60
|
||||
|
||||
# Give the machine which says its name is "bert" IP address
|
||||
# 192.168.0.70 and an infinite lease
|
||||
#dhcp-host=bert,192.168.0.70,infinite
|
||||
|
||||
@@ -149,6 +261,13 @@ bogus-priv
|
||||
# the IP address 192.168.0.60
|
||||
#dhcp-host=id:01:02:02:04,192.168.0.60
|
||||
|
||||
# Always give the InfiniBand interface with hardware address
|
||||
# 80:00:00:48:fe:80:00:00:00:00:00:00:f4:52:14:03:00:28:05:81 the
|
||||
# ip address 192.168.0.61. The client id is derived from the prefix
|
||||
# ff:00:00:00:00:00:02:00:00:02:c9:00 and the last 8 pairs of
|
||||
# hex digits of the hardware address.
|
||||
#dhcp-host=id:ff:00:00:00:00:00:02:00:00:02:c9:00:f4:52:14:03:00:28:05:81,192.168.0.61
|
||||
|
||||
# Always give the host with client identifier "marjorie"
|
||||
# the IP address 192.168.0.60
|
||||
#dhcp-host=id:marjorie,192.168.0.60
|
||||
@@ -158,35 +277,47 @@ bogus-priv
|
||||
# it asks for a DHCP lease.
|
||||
#dhcp-host=judge
|
||||
|
||||
# Never offer DHCP service to a machine whose ethernet
|
||||
# Never offer DHCP service to a machine whose Ethernet
|
||||
# address is 11:22:33:44:55:66
|
||||
#dhcp-host=11:22:33:44:55:66,ignore
|
||||
|
||||
# Ignore any client-id presented by the machine with ethernet
|
||||
# Ignore any client-id presented by the machine with Ethernet
|
||||
# address 11:22:33:44:55:66. This is useful to prevent a machine
|
||||
# being treated differently when running under different OS's or
|
||||
# between PXE boot and OS boot.
|
||||
#dhcp-host=11:22:33:44:55:66,id:*
|
||||
|
||||
# Send extra options which are tagged as "red" to
|
||||
# the machine with ethernet address 11:22:33:44:55:66
|
||||
#dhcp-host=11:22:33:44:55:66,net:red
|
||||
# the machine with Ethernet address 11:22:33:44:55:66
|
||||
#dhcp-host=11:22:33:44:55:66,set:red
|
||||
|
||||
# Send extra options which are tagged as "red" to
|
||||
# any machine with ethernet address starting 11:22:33:
|
||||
#dhcp-host=11:22:33:*:*:*,net:red
|
||||
# any machine with Ethernet address starting 11:22:33:
|
||||
#dhcp-host=11:22:33:*:*:*,set:red
|
||||
|
||||
# Give a fixed IPv6 address and name to client with
|
||||
# DUID 00:01:00:01:16:d2:83:fc:92:d4:19:e2:d8:b2
|
||||
# Note the MAC addresses CANNOT be used to identify DHCPv6 clients.
|
||||
# Note also that the [] around the IPv6 address are obligatory.
|
||||
#dhcp-host=id:00:01:00:01:16:d2:83:fc:92:d4:19:e2:d8:b2, fred, [1234::5]
|
||||
|
||||
# Ignore any clients which are not specified in dhcp-host lines
|
||||
# or /etc/ethers. Equivalent to ISC "deny unknown-clients".
|
||||
# This relies on the special "known" tag which is set when
|
||||
# a host is matched.
|
||||
#dhcp-ignore=tag:!known
|
||||
|
||||
# Send extra options which are tagged as "red" to any machine whose
|
||||
# DHCP vendorclass string includes the substring "Linux"
|
||||
#dhcp-vendorclass=red,Linux
|
||||
#dhcp-vendorclass=set:red,Linux
|
||||
|
||||
# Send extra options which are tagged as "red" to any machine one
|
||||
# of whose DHCP userclass strings includes the substring "accounts"
|
||||
#dhcp-userclass=red,accounts
|
||||
#dhcp-userclass=set:red,accounts
|
||||
|
||||
# Send extra options which are tagged as "red" to any machine whose
|
||||
# MAC address matches the pattern.
|
||||
#dhcp-mac=red,00:60:8C:*:*:*
|
||||
#dhcp-mac=set:red,00:60:8C:*:*:*
|
||||
|
||||
# If this line is uncommented, dnsmasq will read /etc/ethers and act
|
||||
# on the ethernet-address/IP pairs found there just as if they had
|
||||
@@ -196,24 +327,48 @@ bogus-priv
|
||||
|
||||
# Send options to hosts which ask for a DHCP lease.
|
||||
# See RFC 2132 for details of available options.
|
||||
# Common options can be given to dnsmasq by name:
|
||||
# run "dnsmasq --help dhcp" to get a list.
|
||||
# Note that all the common settings, such as netmask and
|
||||
# broadcast address, DNS server and default route, are given
|
||||
# sane defaults by dnsmasq. You very likely will not need any
|
||||
# sane defaults by dnsmasq. You very likely will not need
|
||||
# any dhcp-options. If you use Windows clients and Samba, there
|
||||
# are some options which are recommended, they are detailed at the
|
||||
# end of this section.
|
||||
# For reference, the common options are:
|
||||
# subnet mask - 1
|
||||
# default router - 3
|
||||
# DNS server - 6
|
||||
# broadcast address - 28
|
||||
|
||||
# Override the default route supplied by dnsmasq, which assumes the
|
||||
# router is the same machine as the one running dnsmasq.
|
||||
#dhcp-option=3,1.2.3.4
|
||||
|
||||
# Do the same thing, but using the option name
|
||||
#dhcp-option=option:router,1.2.3.4
|
||||
|
||||
# Override the default route supplied by dnsmasq and send no default
|
||||
# route at all. Note that this only works for the options sent by
|
||||
# default (1, 3, 6, 12, 28) the same line will send a zero-length option
|
||||
# for all other option numbers.
|
||||
#dhcp-option=3
|
||||
|
||||
# Set the NTP time server addresses to 192.168.0.4 and 10.10.0.5
|
||||
#dhcp-option=42,192.168.0.4,10.10.0.5
|
||||
#dhcp-option=option:ntp-server,192.168.0.4,10.10.0.5
|
||||
|
||||
# Send DHCPv6 option. Note [] around IPv6 addresses.
|
||||
#dhcp-option=option6:dns-server,[1234::77],[1234::88]
|
||||
|
||||
# Send DHCPv6 option for namservers as the machine running
|
||||
# dnsmasq and another.
|
||||
#dhcp-option=option6:dns-server,[::],[1234::88]
|
||||
|
||||
# Ask client to poll for option changes every six hours. (RFC4242)
|
||||
#dhcp-option=option6:information-refresh-time,6h
|
||||
|
||||
# Set option 58 client renewal time (T1). Defaults to half of the
|
||||
# lease time if not specified. (RFC2132)
|
||||
#dhcp-option=option:T1,1m
|
||||
|
||||
# Set option 59 rebinding time (T2). Defaults to 7/8 of the
|
||||
# lease time if not specified. (RFC2132)
|
||||
#dhcp-option=option:T2,2m
|
||||
|
||||
# Set the NTP time server address to be the same machine as
|
||||
# is running dnsmasq
|
||||
@@ -234,39 +389,156 @@ bogus-priv
|
||||
|
||||
# Specify an option which will only be sent to the "red" network
|
||||
# (see dhcp-range for the declaration of the "red" network)
|
||||
#dhcp-option=red,42,192.168.1.1
|
||||
# Note that the tag: part must precede the option: part.
|
||||
#dhcp-option = tag:red, option:ntp-server, 192.168.1.1
|
||||
|
||||
# The following DHCP options set up dnsmasq in the same way as is specified
|
||||
# for the ISC dhcpcd in
|
||||
# http://www.samba.org/samba/ftp/docs/textdocs/DHCP-Server-Configuration.txt
|
||||
# https://web.archive.org/web/20040313070105/http://us1.samba.org/samba/ftp/docs/textdocs/DHCP-Server-Configuration.txt
|
||||
# adapted for a typical dnsmasq installation where the host running
|
||||
# dnsmasq is also the host running samba.
|
||||
# you may want to uncomment them if you use Windows clients and Samba.
|
||||
# you may want to uncomment some or all of them if you use
|
||||
# Windows clients and Samba.
|
||||
#dhcp-option=19,0 # option ip-forwarding off
|
||||
#dhcp-option=44,0.0.0.0 # set netbios-over-TCP/IP nameserver(s) aka WINS server(s)
|
||||
#dhcp-option=45,0.0.0.0 # netbios datagram distribution server
|
||||
#dhcp-option=46,8 # netbios node type
|
||||
#dhcp-option=47 # empty netbios scope.
|
||||
|
||||
# Send an empty WPAD option. This may be REQUIRED to get windows 7 to behave.
|
||||
#dhcp-option=252,"\n"
|
||||
|
||||
# Send RFC-3397 DNS domain search DHCP option. WARNING: Your DHCP client
|
||||
# probably doesn't support this......
|
||||
#dhcp-option=119,eng.apple.com,marketing.apple.com
|
||||
#dhcp-option=option:domain-search,eng.apple.com,marketing.apple.com
|
||||
|
||||
# Send RFC-3442 classless static routes (note the netmask encoding)
|
||||
#dhcp-option=121,192.168.1.0/24,1.2.3.4,10.0.0.0/8,5.6.7.8
|
||||
|
||||
# Send encapsulated vendor-class specific options. The vendor-class
|
||||
# is sent as DHCP option 60, and all the options marked with the
|
||||
# vendor class are send encapsulated in DHCP option 43. The meaning of
|
||||
# the options is defined by the vendor-class. This example sets the
|
||||
# mtftp address to 0.0.0.0 for PXEClients
|
||||
# Send vendor-class specific options encapsulated in DHCP option 43.
|
||||
# The meaning of the options is defined by the vendor-class so
|
||||
# options are sent only when the client supplied vendor class
|
||||
# matches the class given here. (A substring match is OK, so "MSFT"
|
||||
# matches "MSFT" and "MSFT 5.0"). This example sets the
|
||||
# mtftp address to 0.0.0.0 for PXEClients.
|
||||
#dhcp-option=vendor:PXEClient,1,0.0.0.0
|
||||
|
||||
# Set the boot filename and tftpd server name and address
|
||||
# for BOOTP. You will only need this is you want to
|
||||
# boot machines over the network.
|
||||
# Send microsoft-specific option to tell windows to release the DHCP lease
|
||||
# when it shuts down. Note the "i" flag, to tell dnsmasq to send the
|
||||
# value as a four-byte integer - that's what microsoft wants. See
|
||||
# http://technet2.microsoft.com/WindowsServer/en/library/a70f1bb7-d2d4-49f0-96d6-4b7414ecfaae1033.mspx?mfr=true
|
||||
#dhcp-option=vendor:MSFT,2,1i
|
||||
|
||||
# Send the Encapsulated-vendor-class ID needed by some configurations of
|
||||
# Etherboot to allow is to recognise the DHCP server.
|
||||
#dhcp-option=vendor:Etherboot,60,"Etherboot"
|
||||
|
||||
# Send options to PXELinux. Note that we need to send the options even
|
||||
# though they don't appear in the parameter request list, so we need
|
||||
# to use dhcp-option-force here.
|
||||
# See http://syslinux.zytor.com/pxe.php#special for details.
|
||||
# Magic number - needed before anything else is recognised
|
||||
#dhcp-option-force=208,f1:00:74:7e
|
||||
# Configuration file name
|
||||
#dhcp-option-force=209,configs/common
|
||||
# Path prefix
|
||||
#dhcp-option-force=210,/tftpboot/pxelinux/files/
|
||||
# Reboot time. (Note 'i' to send 32-bit value)
|
||||
#dhcp-option-force=211,30i
|
||||
|
||||
# Set the boot filename for netboot/PXE. You will only need
|
||||
# this if you want to boot machines over the network and you will need
|
||||
# a TFTP server; either dnsmasq's built-in TFTP server or an
|
||||
# external one. (See below for how to enable the TFTP server.)
|
||||
#dhcp-boot=pxelinux.0
|
||||
|
||||
# The same as above, but use custom tftp-server instead machine running dnsmasq
|
||||
#dhcp-boot=pxelinux,server.name,192.168.1.100
|
||||
|
||||
# Boot for iPXE. The idea is to send two different
|
||||
# filenames, the first loads iPXE, and the second tells iPXE what to
|
||||
# load. The dhcp-match sets the ipxe tag for requests from iPXE.
|
||||
#dhcp-boot=undionly.kpxe
|
||||
#dhcp-match=set:ipxe,175 # iPXE sends a 175 option.
|
||||
#dhcp-boot=tag:ipxe,http://boot.ipxe.org/demo/boot.php
|
||||
|
||||
# Encapsulated options for iPXE. All the options are
|
||||
# encapsulated within option 175
|
||||
#dhcp-option=encap:175, 1, 5b # priority code
|
||||
#dhcp-option=encap:175, 176, 1b # no-proxydhcp
|
||||
#dhcp-option=encap:175, 177, string # bus-id
|
||||
#dhcp-option=encap:175, 189, 1b # BIOS drive code
|
||||
#dhcp-option=encap:175, 190, user # iSCSI username
|
||||
#dhcp-option=encap:175, 191, pass # iSCSI password
|
||||
|
||||
# Test for the architecture of a netboot client. PXE clients are
|
||||
# supposed to send their architecture as option 93. (See RFC 4578)
|
||||
#dhcp-match=peecees, option:client-arch, 0 #x86-32
|
||||
#dhcp-match=itanics, option:client-arch, 2 #IA64
|
||||
#dhcp-match=hammers, option:client-arch, 6 #x86-64
|
||||
#dhcp-match=mactels, option:client-arch, 7 #EFI x86-64
|
||||
|
||||
# Do real PXE, rather than just booting a single file, this is an
|
||||
# alternative to dhcp-boot.
|
||||
#pxe-prompt="What system shall I netboot?"
|
||||
# or with timeout before first available action is taken:
|
||||
#pxe-prompt="Press F8 for menu.", 60
|
||||
|
||||
# Available boot services. for PXE.
|
||||
#pxe-service=x86PC, "Boot from local disk"
|
||||
|
||||
# Loads <tftp-root>/pxelinux.0 from dnsmasq TFTP server.
|
||||
#pxe-service=x86PC, "Install Linux", pxelinux
|
||||
|
||||
# Loads <tftp-root>/pxelinux.0 from TFTP server at 1.2.3.4.
|
||||
# Beware this fails on old PXE ROMS.
|
||||
#pxe-service=x86PC, "Install Linux", pxelinux, 1.2.3.4
|
||||
|
||||
# Use bootserver on network, found my multicast or broadcast.
|
||||
#pxe-service=x86PC, "Install windows from RIS server", 1
|
||||
|
||||
# Use bootserver at a known IP address.
|
||||
#pxe-service=x86PC, "Install windows from RIS server", 1, 1.2.3.4
|
||||
|
||||
# If you have multicast-FTP available,
|
||||
# information for that can be passed in a similar way using options 1
|
||||
# to 5. See page 19 of
|
||||
# http://download.intel.com/design/archives/wfm/downloads/pxespec.pdf
|
||||
|
||||
|
||||
# Enable dnsmasq's built-in TFTP server
|
||||
#enable-tftp
|
||||
|
||||
# Set the root directory for files available via FTP.
|
||||
#tftp-root=/var/ftpd
|
||||
|
||||
# Do not abort if the tftp-root is unavailable
|
||||
#tftp-no-fail
|
||||
|
||||
# Make the TFTP server more secure: with this set, only files owned by
|
||||
# the user dnsmasq is running as will be send over the net.
|
||||
#tftp-secure
|
||||
|
||||
# This option stops dnsmasq from negotiating a larger blocksize for TFTP
|
||||
# transfers. It will slow things down, but may rescue some broken TFTP
|
||||
# clients.
|
||||
#tftp-no-blocksize
|
||||
|
||||
# Set the boot file name only when the "red" tag is set.
|
||||
#dhcp-boot=tag:red,pxelinux.red-net
|
||||
|
||||
# An example of dhcp-boot with an external TFTP server: the name and IP
|
||||
# address of the server are given after the filename.
|
||||
# Can fail with old PXE ROMS. Overridden by --pxe-service.
|
||||
#dhcp-boot=/var/ftpd/pxelinux.0,boothost,192.168.0.3
|
||||
|
||||
# If there are multiple external tftp servers having a same name
|
||||
# (using /etc/hosts) then that name can be specified as the
|
||||
# tftp_servername (the third option to dhcp-boot) and in that
|
||||
# case dnsmasq resolves this name and returns the resultant IP
|
||||
# addresses in round robin fashion. This facility can be used to
|
||||
# load balance the tftp load among a set of servers.
|
||||
#dhcp-boot=/var/ftpd/pxelinux.0,boothost,tftp_server_name
|
||||
|
||||
# Set the limit on DHCP leases, the default is 150
|
||||
#dhcp-lease-max=150
|
||||
|
||||
@@ -279,19 +551,33 @@ bogus-priv
|
||||
# and take over the lease for any client which broadcasts on the network,
|
||||
# whether it has a record of the lease or not. This avoids long timeouts
|
||||
# when a machine wakes up on a new network. DO NOT enable this if there's
|
||||
# the slighest chance that you might end up accidentally configuring a DHCP
|
||||
# server for your campus/company accidentally. The ISC server uses the same
|
||||
# the slightest chance that you might end up accidentally configuring a DHCP
|
||||
# server for your campus/company accidentally. The ISC server uses
|
||||
# the same option, and this URL provides more information:
|
||||
# http://www.isc.org/index.pl?/sw/dhcp/authoritative.php
|
||||
# http://www.isc.org/files/auth.html
|
||||
#dhcp-authoritative
|
||||
|
||||
# Set the DHCP server to enable DHCPv4 Rapid Commit Option per RFC 4039.
|
||||
# In this mode it will respond to a DHCPDISCOVER message including a Rapid Commit
|
||||
# option with a DHCPACK including a Rapid Commit option and fully committed address
|
||||
# and configuration information. This must only be enabled if either the server is
|
||||
# the only server for the subnet, or multiple servers are present and they each
|
||||
# commit a binding for all clients.
|
||||
#dhcp-rapid-commit
|
||||
|
||||
# Run an executable when a DHCP lease is created or destroyed.
|
||||
# The arguments sent to the script are "add" or "del",
|
||||
# then the MAC address, the IP address and finally the hostname
|
||||
# if there is one.
|
||||
#dhcp-script=/bin/echo
|
||||
|
||||
# Set the cachesize here.
|
||||
#cache-size=150
|
||||
|
||||
# If you want to disable negative caching, uncomment this.
|
||||
#no-negcache
|
||||
|
||||
# Normally responses which come form /etc/hosts and the DHCP lease
|
||||
# Normally responses which come from /etc/hosts and the DHCP lease
|
||||
# file have Time-To-Live set as zero, which conventionally means
|
||||
# do not cache further. If you are happy to trade lower load on the
|
||||
# server for potentially stale date, you can set a time-to-live (in
|
||||
@@ -311,7 +597,8 @@ bogus-priv
|
||||
#alias=1.2.3.4,5.6.7.8
|
||||
# and this maps 1.2.3.x to 5.6.7.x
|
||||
#alias=1.2.3.0,5.6.7.0,255.255.255.0
|
||||
|
||||
# and this maps 192.168.0.10->192.168.0.40 to 10.0.0.10->10.0.0.40
|
||||
#alias=192.168.0.10-192.168.0.40,10.0.0.0,255.255.255.0
|
||||
|
||||
# Change these lines if you want dnsmasq to serve MX records.
|
||||
|
||||
@@ -341,11 +628,11 @@ bogus-priv
|
||||
# set for this to work.)
|
||||
|
||||
# A SRV record sending LDAP for the example.com domain to
|
||||
# ldapserver.example.com port 289
|
||||
# ldapserver.example.com port 389
|
||||
#srv-host=_ldap._tcp.example.com,ldapserver.example.com,389
|
||||
|
||||
# A SRV record sending LDAP for the example.com domain to
|
||||
# ldapserver.example.com port 289 (using domain=)
|
||||
# ldapserver.example.com port 389 (using domain=)
|
||||
#domain=example.com
|
||||
#srv-host=_ldap._tcp,ldapserver.example.com,389
|
||||
|
||||
@@ -357,6 +644,11 @@ bogus-priv
|
||||
# example.com
|
||||
#srv-host=_ldap._tcp.example.com
|
||||
|
||||
# The following line shows how to make dnsmasq serve an arbitrary PTR
|
||||
# record. This is useful for DNS-SD. (Note that the
|
||||
# domain-name expansion done for SRV records _does_not
|
||||
# occur for PTR records.)
|
||||
#ptr-record=_http._tcp.dns-sd-services,"New Employee Page._http._tcp.dns-sd-services"
|
||||
|
||||
# Change the following lines to enable dnsmasq to serve TXT records.
|
||||
# These are used for things like SPF and zeroconf. (Note that the
|
||||
@@ -364,15 +656,34 @@ bogus-priv
|
||||
# occur for TXT records.)
|
||||
|
||||
#Example SPF.
|
||||
#txt-record=example.com,v=spf1 a -all
|
||||
#txt-record=example.com,"v=spf1 a -all"
|
||||
|
||||
#Example zeroconf
|
||||
#txt-record=_http._tcp.example.com,name=value,paper=A4
|
||||
|
||||
# Provide an alias for a "local" DNS name. Note that this _only_ works
|
||||
# for targets which are names from DHCP or /etc/hosts. Give host
|
||||
# "bert" another name, bertrand
|
||||
#cname=bertrand,bert
|
||||
|
||||
# For debugging purposes, log each DNS query as it passes through
|
||||
# dnsmasq.
|
||||
#log-queries
|
||||
|
||||
# Include a another lot of configuration options.
|
||||
# Log lots of extra information about DHCP transactions.
|
||||
#log-dhcp
|
||||
|
||||
# Include another lot of configuration options.
|
||||
#conf-file=/etc/dnsmasq.more.conf
|
||||
#conf-dir=/etc/dnsmasq.d
|
||||
|
||||
# Include all the files in a directory except those ending in .bak
|
||||
#conf-dir=/etc/dnsmasq.d,.bak
|
||||
|
||||
# Include all files in a directory which end in .conf
|
||||
#conf-dir=/etc/dnsmasq.d/,*.conf
|
||||
|
||||
# If a DHCP client claims that its name is "wpad", ignore that.
|
||||
# This fixes a security hole. see CERT Vulnerability VU#598349
|
||||
#dhcp-name-match=set:wpad-ignore,wpad
|
||||
#dhcp-ignore-names=tag:wpad-ignore
|
||||
|
||||
181
doc.html
181
doc.html
@@ -1,124 +1,99 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE> Dnsmasq - a DNS forwarder for NAT firewalls.</TITLE>
|
||||
<TITLE> Dnsmasq - network services for small networks.</TITLE>
|
||||
<link rel="icon" href="http://www.thekelleys.org.uk/dnsmasq/images/favicon.ico">
|
||||
</HEAD>
|
||||
<BODY BGCOLOR="WHITE">
|
||||
<H1 ALIGN=center>Dnsmasq</H1>
|
||||
Dnsmasq is a lightweight, easy to configure DNS forwarder and DHCP
|
||||
server. It is designed to provide DNS and, optionally, DHCP, to a
|
||||
small network. It can serve the names of local machines which are
|
||||
not in the global DNS. The DHCP server integrates with the DNS
|
||||
server and allows machines with DHCP-allocated addresses
|
||||
to appear in the DNS with names configured either in each host or
|
||||
in a central configuration file. Dnsmasq supports static and dynamic
|
||||
DHCP leases and BOOTP for network booting of diskless machines.
|
||||
<table width="100%" border="0" cellpadding="0" cellspacing="0">
|
||||
<tr>
|
||||
<td align="left" valign="middle"><img border="0" src="http://www.thekelleys.org.uk/dnsmasq/images/icon.png" /></td>
|
||||
<td align="middle" valign="middle"><h1>Dnsmasq</h1></td>
|
||||
<td align="right" valign="middle"><img border="0" src="http://www.thekelleys.org.uk/dnsmasq/images/icon.png" /></td></tr>
|
||||
</table>
|
||||
Dnsmasq provides network infrastructure for small networks: DNS, DHCP, router advertisement and network boot. It is designed to be
|
||||
lightweight and have a small footprint, suitable for resource constrained routers and firewalls. It has also been widely used
|
||||
for tethering on smartphones and portable hotspots, and to support virtual networking in virtualisation frameworks.
|
||||
Supported platforms include Linux (with glibc and uclibc), Android, *BSD, and Mac OS X. Dnsmasq is included in most
|
||||
Linux distributions and the ports systems of FreeBSD, OpenBSD and NetBSD. Dnsmasq provides full IPv6 support.
|
||||
|
||||
<P>
|
||||
Dnsmasq is targeted at home networks using NAT and
|
||||
connected to the internet via a modem, cable-modem or ADSL
|
||||
connection but would be a good choice for any small network where low
|
||||
resource use and ease of configuration are important.
|
||||
<P>
|
||||
Supported platforms include Linux (with glibc and uclibc), *BSD and
|
||||
Mac OS X.
|
||||
Dnsmasq is included in at least the following Linux distributions:
|
||||
Gentoo, Debian, Slackware, Suse,
|
||||
Smoothwall, IP-Cop, floppyfw, Firebox, LEAF, Freesco, fli4l, CoyoteLinux and
|
||||
Clarkconnect. It is also available as a FreeBSD port and is used in
|
||||
Linksys wireless routers and the m0n0wall project.
|
||||
<P>
|
||||
Dnsmasq provides the following features:
|
||||
The DNS subsystem provides a local DNS server for the network, with forwarding of all query types to upstream recursive DNS servers and
|
||||
caching of common record types (A, AAAA, CNAME and PTR, also DNSKEY and DS when DNSSEC is enabled).
|
||||
<DIR>
|
||||
|
||||
<LI>
|
||||
The DNS configuration of machines behind the firewall is simple and
|
||||
doesn't depend on the details of the ISP's dns servers
|
||||
<LI>
|
||||
Clients which try to do DNS lookups while a modem link to the
|
||||
internet is down will time out immediately.
|
||||
</LI>
|
||||
<LI>
|
||||
Dnsmasq will serve names from the /etc/hosts file on the firewall
|
||||
machine: If the names of local machines are there, then they can all
|
||||
be addressed without having to maintain /etc/hosts on each machine.
|
||||
</LI>
|
||||
<LI>
|
||||
The integrated DHCP server supports static and dynamic DHCP leases and
|
||||
multiple networks and IP ranges. It works across BOOTP relays and
|
||||
supports DHCP options including RFC3397 DNS search lists.
|
||||
Machines which are configured by DHCP have their names automatically
|
||||
included in the DNS and the names can specified by each machine or
|
||||
centrally by associating a name with a MAC address in the dnsmasq
|
||||
config file.
|
||||
</LI>
|
||||
<LI>
|
||||
Dnsmasq caches internet addresses (A records and AAAA records) and address-to-name
|
||||
mappings (PTR records), reducing the load on upstream servers and
|
||||
improving performance (especially on modem connections).
|
||||
</LI>
|
||||
<LI>
|
||||
Dnsmasq can be configured to automatically pick up the addresses of
|
||||
it's upstream nameservers from ppp or dhcp configuration. It will
|
||||
automatically reload this information if it changes. This facility
|
||||
will be of particular interest to maintainers of Linux firewall
|
||||
distributions since it allows dns configuration to be made automatic.
|
||||
</LI>
|
||||
<LI>
|
||||
On IPv6-enabled boxes, dnsmasq can both talk to upstream servers via IPv6
|
||||
and offer DNS service via IPv6. On dual-stack (IPv4 and IPv6) boxes it talks
|
||||
both protocols and can even act as IPv6-to-IPv4 or IPv4-to-IPv6 forwarder.
|
||||
</LI>
|
||||
<LI>
|
||||
Dnsmasq can be configured to send queries for certain domains to
|
||||
upstream servers handling only those domains. This makes integration
|
||||
with private DNS systems easy.
|
||||
</LI>
|
||||
<LI>
|
||||
Dnsmasq supports MX records and can be configured to return MX records
|
||||
for any or all local machines.
|
||||
</LI>
|
||||
<LI>Local DNS names can be defined by reading /etc/hosts, by importing names from the DHCP subsystem, or by configuration of a wide range of useful record types.</LI>
|
||||
<LI>Upstream servers can be configured in a variety of convenient ways, including dynamic configuration as these change on moving upstream network.
|
||||
<LI>Authoritative DNS mode allows local DNS names may be exported to zone in the global DNS. Dnsmasq acts as authoritative server for this zone, and also provides
|
||||
zone transfer to secondaries for the zone, if required.</LI>
|
||||
<LI>DNSSEC validation may be performed on DNS replies from upstream nameservers, providing security against spoofing and cache poisoning.</LI>
|
||||
<LI>Specified sub-domains can be directed to their own upstream DNS servers, making VPN configuration easy.</LI>
|
||||
<LI>Internationalised domain names are supported.
|
||||
</DIR>
|
||||
|
||||
<H2>Download.</H2>
|
||||
|
||||
<A HREF="http://www.thekelleys.org.uk/dnsmasq/"> Download</A> dnsmasq here.
|
||||
The tarball includes this documentation, source, manpage and control files for building .rpms.
|
||||
There are also pre-built i386 .rpms, and a
|
||||
<A HREF="CHANGELOG"> CHANGELOG</A>.
|
||||
Dnsmasq is part of the Debian distribution, it can be downloaded from
|
||||
<A HREF="http://ftp.debian.org/debian/pool/main/d/dnsmasq/"> here</A> or installed using <TT>apt</TT>.
|
||||
<P>
|
||||
The DHCP subsystem supports DHCPv4, DHCPv6, BOOTP and PXE.
|
||||
<DIR>
|
||||
<LI> Both static and dynamic DHCP leases are supported, along with stateless mode in DHCPv6.</LI>
|
||||
<LI> The PXE system is a full PXE server, supporting netboot menus and multiple architecture support. It
|
||||
includes proxy-mode, where the PXE system co-operates with another DHCP server.</LI>
|
||||
<LI> There is a built in read-only TFTP server to support netboot.</LI>
|
||||
<LI> Machines which are configured by DHCP have their names automatically
|
||||
included in the DNS and the names can specified by each machine or
|
||||
centrally by associating a name with a MAC address or UID in the dnsmasq
|
||||
configuration file.</LI>
|
||||
</DIR>
|
||||
<P>
|
||||
The Router Advertisement subsystem provides basic autoconfiguration for IPv6 hosts. It can be used stand-alone or in conjunction with DHCPv6.
|
||||
<DIR>
|
||||
<LI> The M and O bits are configurable, to control hosts' use of DHCPv6.</LI>
|
||||
<LI> Router advertisements can include the RDNSS option.</LI>
|
||||
<LI> There is a mode which uses name information from DHCPv4 configuration to provide DNS entries
|
||||
for autoconfigured IPv6 addresses which would otherwise be anonymous.</LI>
|
||||
</DIR>
|
||||
<P>
|
||||
|
||||
For extra compactness, unused features may be omitted at compile time.
|
||||
|
||||
|
||||
<H2>Building rpms.</H2>
|
||||
Assuming you have the relevant tools installed, you can rebuild .rpms simply by running (as root)
|
||||
<H2>Get code.</H2>
|
||||
|
||||
<PRE>
|
||||
rpmbuild -ta dnsmasq-xxx.tar.gz
|
||||
</PRE>
|
||||
<A HREF="http://www.thekelleys.org.uk/dnsmasq/">Download</A> dnsmasq here.
|
||||
The tarball includes this documentation, source, and manpage.
|
||||
There is also a <A HREF="CHANGELOG"> CHANGELOG</A> and a <A HREF="FAQ">FAQ</A>.
|
||||
|
||||
Note for Suse users: you will need to re-compress the tar file as
|
||||
bzip2 before building using the commands
|
||||
<PRE>
|
||||
gunzip dnsmasq-xxx.tar.gz
|
||||
bzip2 dnsmasq-zzz.tar
|
||||
</PRE>
|
||||
Dnsmasq has a git repository which contains the complete release
|
||||
history of version 2 and development history from 2.60. You can
|
||||
<A HREF="http://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=summary">browse</A>
|
||||
the repo, or get a copy using git protocol with the command
|
||||
|
||||
<PRE><TT>git clone git://thekelleys.org.uk/dnsmasq.git </TT></PRE>
|
||||
|
||||
or
|
||||
|
||||
<PRE><TT>git clone http://thekelleys.org.uk/git/dnsmasq.git </TT></PRE>
|
||||
|
||||
<H2>Links.</H2>
|
||||
There is an article in German on dnsmasq at <A
|
||||
HREF="http://www.linuxnetmag.com/de/issue7/m7dnsmasq1.html">http://www.linuxnetmag.com/de/issue7/m7dnsmasq1.html</A>
|
||||
and Damien Raude-Morvan has one in French at <A HREF="http://www.drazzib.com/docs-dnsmasq.html">http://www.drazzib.com/docs-dnsmasq.html</A>
|
||||
There is a good article about dnsmasq at <A
|
||||
HREF="http://www.enterprisenetworkingplanet.com/netos/article.php/3377351">http://www.enterprisenetworkingplanet.com/netos/article.php/3377351</A>
|
||||
and Ilya Evseev has an article in Russian about dnsmasq to be found at <A HREF="http://ilya-evseev.narod.ru/articles/dnsmasq"> http://ilya-evseev.narod.ru/articles/dnsmasq</A>
|
||||
<H2>License.</H2>
|
||||
Dnsmasq is distributed under the GPL. See the file COPYING in the distribution
|
||||
Dnsmasq is distributed under the GPL, version 2 or version 3 at your discretion. See the files COPYING and COPYING-v3 in the distribution
|
||||
for details.
|
||||
|
||||
<H2>Contact.</H2>
|
||||
There is a dnsmasq mailing list at <A
|
||||
HREF="http://lists.thekelleys.org.uk/mailman/listinfo/dnsmasq-discuss">
|
||||
http://lists.thekelleys.org.uk/mailman/listinfo/dnsmasq-discuss</A> which should be the
|
||||
first location for queries, bugreports, suggestions etc.
|
||||
Dnsmasq was written by Simon Kelley. You can contact me at <A
|
||||
first location for queries, bugreports, suggestions etc. The list is mirrored, with a
|
||||
search facility, at <A HREF="https://www.mail-archive.com/dnsmasq-discuss@lists.thekelleys.org.uk/">
|
||||
https://www.mail-archive.com/dnsmasq-discuss@lists.thekelleys.org.uk/</A>.
|
||||
You can contact me at <A
|
||||
HREF="mailto:simon@thekelleys.org.uk">simon@thekelleys.org.uk</A>.
|
||||
</BODY>
|
||||
|
||||
<H2>Donations.</H2>
|
||||
Dnsmasq is mainly written and maintained by Simon Kelley. For most of its life, dnsmasq has been a spare-time project.
|
||||
These days I'm working on it as my main activity.
|
||||
I don't have an employer or anyone who pays me regularly to work on dnsmasq. If you'd like to make
|
||||
a contribution towards my expenses, please use the donation button below.
|
||||
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top">
|
||||
<input type="hidden" name="cmd" value="_s-xclick">
|
||||
<input type="hidden" name="hosted_button_id" value="V3X9GVW5GX6DA">
|
||||
<input type="image" src="https://www.paypalobjects.com/en_US/GB/i/btn/btn_donateCC_LG.gif" border="0" name="submit" alt="PayPal – The safer, easier way to pay online.">
|
||||
<img alt="" border="0" src="https://www.paypalobjects.com/en_GB/i/scr/pixel.gif" width="1" height="1">
|
||||
</form>
|
||||
</BODY>
|
||||
</HTML>
|
||||
|
||||
12
logo/README
Normal file
12
logo/README
Normal file
@@ -0,0 +1,12 @@
|
||||
Dnsmasq logo, contributed by Justin Clift.
|
||||
|
||||
The source format is Inkscape SVG vector format, which is scalable and
|
||||
easy to export to other formats. For convenience I've included a 56x31
|
||||
png export and a 16x16 ico suitable for use as a web favicon.
|
||||
|
||||
Simon Kelley, 22/10/2010
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
BIN
logo/favicon.ico
Normal file
BIN
logo/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
BIN
logo/icon.png
Normal file
BIN
logo/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.8 KiB |
157
logo/icon.svg
Normal file
157
logo/icon.svg
Normal file
@@ -0,0 +1,157 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
width="56"
|
||||
height="31"
|
||||
viewBox="0 0 56 31"
|
||||
enable-background="new 0 0 72.833 46.667"
|
||||
xml:space="preserve"
|
||||
id="svg2"
|
||||
inkscape:version="0.47 r22583"
|
||||
sodipodi:docname="dnsmasq_icon.svg"
|
||||
inkscape:export-filename="/x/centos_home/jc/workspace/git_repos/libvirt-media/libvirt-media/png/dnsmasq_icon.png"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90"><metadata
|
||||
id="metadata27"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs25"><inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 23.3335 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="72.833 : 23.3335 : 1"
|
||||
inkscape:persp3d-origin="36.4165 : 15.555667 : 1"
|
||||
id="perspective4857" />
|
||||
<filter
|
||||
id="filter3802"
|
||||
inkscape:label="filter1"
|
||||
color-interpolation-filters="sRGB" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#SVGID_3_"
|
||||
id="linearGradient4929"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="30.564501"
|
||||
y1="-8.8144999"
|
||||
x2="32.937"
|
||||
y2="32.715599" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#SVGID_3_"
|
||||
id="linearGradient5798"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="30.564501"
|
||||
y1="-8.8144999"
|
||||
x2="32.937"
|
||||
y2="32.715599" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#SVGID_3_"
|
||||
id="linearGradient5812"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="30.564501"
|
||||
y1="-8.8144999"
|
||||
x2="32.937"
|
||||
y2="32.715599" /><filter
|
||||
id="filter6262"
|
||||
inkscape:label="Drop shadow"
|
||||
width="1.5"
|
||||
height="1.5"
|
||||
x="-0.25"
|
||||
y="-0.25"
|
||||
color-interpolation-filters="sRGB"><feGaussianBlur
|
||||
id="feGaussianBlur6264"
|
||||
in="SourceAlpha"
|
||||
stdDeviation="2.500000"
|
||||
result="blur" /><feColorMatrix
|
||||
id="feColorMatrix6266"
|
||||
result="bluralpha"
|
||||
type="matrix"
|
||||
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0.500000 0 " /><feOffset
|
||||
id="feOffset6268"
|
||||
in="bluralpha"
|
||||
dx="2.700000"
|
||||
dy="2.600000"
|
||||
result="offsetBlur" /><feMerge
|
||||
id="feMerge6270"><feMergeNode
|
||||
id="feMergeNode6272"
|
||||
in="offsetBlur" /><feMergeNode
|
||||
id="feMergeNode6274"
|
||||
in="SourceGraphic" /></feMerge></filter></defs><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1568"
|
||||
inkscape:window-height="1076"
|
||||
id="namedview23"
|
||||
showgrid="false"
|
||||
inkscape:zoom="8"
|
||||
inkscape:cx="31.966768"
|
||||
inkscape:cy="21.211869"
|
||||
inkscape:window-x="567"
|
||||
inkscape:window-y="328"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="layer1"
|
||||
inkscape:showpageshadow="false"
|
||||
showborder="true" />
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
inkscape:label="dnsmasq"
|
||||
style="display:inline"
|
||||
transform="translate(5.2838057,-15.545371)"><g
|
||||
id="g3790"
|
||||
transform="matrix(0.8183832,0,0,0.8183832,65.304897,9.8747678)"
|
||||
style="filter:url(#filter6262)"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90"><g
|
||||
transform="translate(-91.018462,1.0687099)"
|
||||
id="g9">
|
||||
<path
|
||||
style="fill:#6700ad"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path11"
|
||||
d="M 54.997,12.151 C 50.083,9.132 43.29,7.266 35.791,7.266 c -7.5,0 -14.29,1.866 -19.204,4.885 -4.915,3.016 -7.956,7.184 -7.956,11.789 0,4.604 3.041,8.772 7.956,11.788 4.914,3.02 11.704,-4.271 19.204,-4.271 7.499,0 14.292,7.291 19.206,4.271 4.914,-3.016 7.955,-7.185 7.955,-11.788 0,-4.606 -3.041,-8.773 -7.955,-11.789 z M 24.996,24.318 c -2.698,0 -4.885,-0.922 -4.885,-2.061 0,-1.14 2.187,-2.063 4.885,-2.063 2.697,0 4.885,0.924 4.885,2.063 0,1.139 -2.188,2.061 -4.885,2.061 z m 21.501,0.191 c -2.686,0 -4.861,-0.856 -4.861,-1.912 0,-1.054 2.176,-1.911 4.861,-1.911 2.685,0 4.863,0.857 4.863,1.911 0,1.056 -2.178,1.912 -4.863,1.912 z" />
|
||||
<path
|
||||
style="fill:none;stroke:#ffb616;stroke-width:1.85353255"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path13"
|
||||
d="M 54.997,12.151 C 50.083,9.132 43.29,7.266 35.791,7.266 c -7.5,0 -14.29,1.866 -19.204,4.885 -4.915,3.016 -7.956,7.184 -7.956,11.789 0,4.604 3.041,8.772 7.956,11.788 4.914,3.02 11.704,-4.271 19.204,-4.271 7.499,0 14.292,7.291 19.206,4.271 4.914,-3.016 7.955,-7.185 7.955,-11.788 0,-4.606 -3.041,-8.773 -7.955,-11.789 z M 24.996,24.318 c -2.698,0 -4.885,-0.922 -4.885,-2.061 0,-1.14 2.187,-2.063 4.885,-2.063 2.697,0 4.885,0.924 4.885,2.063 0,1.139 -2.188,2.061 -4.885,2.061 z m 21.501,0.191 c -2.686,0 -4.861,-0.856 -4.861,-1.912 0,-1.054 2.176,-1.911 4.861,-1.911 2.685,0 4.863,0.857 4.863,1.911 0,1.056 -2.178,1.912 -4.863,1.912 z" />
|
||||
</g><g
|
||||
transform="translate(-91.018462,1.0687099)"
|
||||
id="Layer_2">
|
||||
<linearGradient
|
||||
y2="32.715599"
|
||||
x2="32.937"
|
||||
y1="-8.8144999"
|
||||
x1="30.564501"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="SVGID_3_">
|
||||
<stop
|
||||
id="stop17"
|
||||
style="stop-color:#FFFFFF;stop-opacity:0.73"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop19"
|
||||
style="stop-color:#FFFFFF;stop-opacity:0"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:url(#linearGradient5812)"
|
||||
id="path21"
|
||||
d="m 54.1,15.361 c -0.924,1.078 -2.782,1.265 -3.857,1.06 C 38,14.083 22.75,12.75 16.027,23.031 14.858,24.819 11.992,25.39 10.293,23.887 8.631,22.417 13.105,15.804 17.646,13.033 22.194,10.252 28.474,8.53 35.41,8.53 c 6.936,0 13.215,1.722 17.756,4.502 0.731,0.442 1.627,1.52 0.934,2.329 z" />
|
||||
</g></g></g></svg>
|
||||
|
After Width: | Height: | Size: 6.0 KiB |
2582
man/dnsmasq.8
2582
man/dnsmasq.8
File diff suppressed because it is too large
Load Diff
1522
man/es/dnsmasq.8
Normal file
1522
man/es/dnsmasq.8
Normal file
File diff suppressed because it is too large
Load Diff
2375
man/fr/dnsmasq.8
Normal file
2375
man/fr/dnsmasq.8
Normal file
File diff suppressed because it is too large
Load Diff
2583
po/pt_BR.po
2583
po/pt_BR.po
File diff suppressed because it is too large
Load Diff
@@ -1,27 +0,0 @@
|
||||
This is a patch against SuSEfirewall2-3.1-206 (SuSE 9.x and older)
|
||||
It fixes the depancy from the dns daemon name 'named'
|
||||
After appending the patch, the SuSEfirewall is again able to autodetect
|
||||
the dnsmasq named service.
|
||||
This is a very old bug in the SuSEfirewall script.
|
||||
The SuSE people think the name of the dns server will allways 'named'
|
||||
|
||||
|
||||
--- /sbin/SuSEfirewall2.orig 2004-01-23 13:30:09.000000000 +0100
|
||||
+++ /sbin/SuSEfirewall2 2004-01-23 13:31:56.000000000 +0100
|
||||
@@ -764,7 +764,7 @@
|
||||
echo 'FW_ALLOW_INCOMING_HIGHPORTS_UDP should be set to yes, if you are running a DNS server!'
|
||||
|
||||
test "$FW_SERVICE_AUTODETECT" = yes -o "$FW_SERVICE_AUTODETECT" = dmz -o "$FW_SERVICE_AUTODETECT" = ext && {
|
||||
- test "$FW_SERVICE_DNS" = no -a '!' "$START_NAMED" = no && check_srv named && {
|
||||
+ test "$FW_SERVICE_DNS" = no -a '!' "$START_NAMED" = no && check_srv dnsmasq && {
|
||||
echo -e 'Warning: detected activated named, enabling FW_SERVICE_DNS!
|
||||
You still have to allow tcp/udp port 53 on internal, dmz and/or external.'
|
||||
FW_SERVICE_DNS=$FW_SERVICE_AUTODETECT
|
||||
@@ -878,7 +878,7 @@
|
||||
test -e /etc/resolv.conf || echo "Warning: /etc/resolv.conf not found"
|
||||
# Get ports/IP bindings of NAMED/SQUID
|
||||
test "$FW_SERVICE_DNS" = yes -o "$FW_SERVICE_DNS" = dmz -o "$FW_SERVICE_DNS" = ext -o "$START_NAMED" = yes && DNS_PORT=`$LSOF -i -n -P | \
|
||||
- $AWK -F: '/^named .* UDP / {print $2}'| $GREP -vw 53 | $SORT -un`
|
||||
+ $AWK -F: '/^dnsmasq .* UDP / {print $2}'| $GREP -vw 53 | $SORT -un`
|
||||
test "$FW_SERVICE_SQUID" = yes -o "$FW_SERVICE_SQUID" = dmz -o "$FW_SERVICE_SQUID" = ext -o "$START_SQUID" = yes && SQUID_PORT=`$LSOF -i -n -P | \
|
||||
$AWK -F: '/^squid .* UDP/ {print $2}'| $SORT -un`
|
||||
@@ -1,23 +0,0 @@
|
||||
--- man/dnsmasq.8 2004-08-08 20:57:56.000000000 +0200
|
||||
+++ man/dnsmasq.8 2004-08-12 00:40:01.000000000 +0200
|
||||
@@ -69,7 +69,7 @@
|
||||
.TP
|
||||
.B \-g, --group=<groupname>
|
||||
Specify the group which dnsmasq will run
|
||||
-as. The defaults to "dip", if available, to facilitate access to
|
||||
+as. The defaults to "dialout", if available, to facilitate access to
|
||||
/etc/ppp/resolv.conf which is not normally world readable.
|
||||
.TP
|
||||
.B \-v, --version
|
||||
--- src/config.h 2004-08-11 11:39:18.000000000 +0200
|
||||
+++ src/config.h 2004-08-12 00:40:01.000000000 +0200
|
||||
@@ -44,7 +44,7 @@
|
||||
#endif
|
||||
#define DEFLEASE 3600 /* default lease time, 1 hour */
|
||||
#define CHUSER "nobody"
|
||||
-#define CHGRP "dip"
|
||||
+#define CHGRP "dialout"
|
||||
#define DHCP_SERVER_PORT 67
|
||||
#define DHCP_CLIENT_PORT 68
|
||||
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Startup script for the DNS caching server
|
||||
#
|
||||
# chkconfig: 2345 99 01
|
||||
# description: This script starts your DNS caching server
|
||||
# processname: dnsmasq
|
||||
# pidfile: /var/run/dnsmasq.pid
|
||||
|
||||
# Source function library.
|
||||
. /etc/rc.d/init.d/functions
|
||||
|
||||
# Source networking configuration.
|
||||
. /etc/sysconfig/network
|
||||
|
||||
# Check that networking is up.
|
||||
[ ${NETWORKING} = "no" ] && exit 0
|
||||
|
||||
dnsmasq=/usr/sbin/dnsmasq
|
||||
[ -f $dnsmasq ] || exit 0
|
||||
|
||||
# change this line if you want dnsmasq to serve an MX record for
|
||||
# the host it is running on.
|
||||
MAILHOSTNAME=""
|
||||
# change this line if you want dns to get its upstream servers from
|
||||
# somewhere other that /etc/resolv.conf
|
||||
RESOLV_CONF=""
|
||||
# change this if you want dnsmasq to cache any "hostname" or "client-hostname" from
|
||||
# a dhcpd's lease file
|
||||
DHCP_LEASE="/var/lib/dhcp/dhcpd.leases"
|
||||
DOMAIN_SUFFIX=`dnsdomainname`
|
||||
|
||||
OPTIONS=""
|
||||
|
||||
if [ ! -z "${MAILHOSTNAME}" ]; then
|
||||
OPTIONS="$OPTIONS -m $MAILHOSTNAME"
|
||||
fi
|
||||
|
||||
if [ ! -z "${RESOLV_CONF}" ]; then
|
||||
OPTIONS="$OPTIONS -r $RESOLV_CONF"
|
||||
fi
|
||||
|
||||
if [ ! -z "${DHCP_LEASE}" ]; then
|
||||
OPTIONS="$OPTIONS -l $DHCP_LEASE"
|
||||
fi
|
||||
|
||||
if [ ! -z "${DOMAIN_SUFFIX}" ]; then
|
||||
OPTIONS="$OPTIONS -s $DOMAIN_SUFFIX"
|
||||
fi
|
||||
|
||||
RETVAL=0
|
||||
|
||||
# See how we were called.
|
||||
case "$1" in
|
||||
start)
|
||||
echo -n "Starting dnsmasq: "
|
||||
daemon $dnsmasq $OPTIONS
|
||||
RETVAL=$?
|
||||
echo
|
||||
[ $RETVAL -eq 0 ] && touch /var/lock/subsys/dnsmasq
|
||||
;;
|
||||
stop)
|
||||
if test "x`pidof dnsmasq`" != x; then
|
||||
echo -n "Shutting down dnsmasq: "
|
||||
killproc dnsmasq
|
||||
fi
|
||||
RETVAL=$?
|
||||
echo
|
||||
[ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/dnsmasq /var/run/dnsmasq.pid
|
||||
;;
|
||||
status)
|
||||
status dnsmasq
|
||||
RETVAL=$?
|
||||
;;
|
||||
restart|reload)
|
||||
$0 stop
|
||||
$0 start
|
||||
RETVAL=$?
|
||||
;;
|
||||
condrestart)
|
||||
if test "x`/sbin/pidof dnsmasq`" != x; then
|
||||
$0 stop
|
||||
$0 start
|
||||
RETVAL=$?
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {start|stop|restart|reload|condrestart|status}"
|
||||
exit 1
|
||||
esac
|
||||
|
||||
exit $RETVAL
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
#! /bin/sh
|
||||
#
|
||||
# init.d/dnsmasq
|
||||
#
|
||||
### BEGIN INIT INFO
|
||||
# Provides: dnsmasq
|
||||
# Required-Start: $network $remote_fs $syslog
|
||||
# Required-Stop:
|
||||
# Default-Start: 3 5
|
||||
# Default-Stop:
|
||||
# Description: Starts internet name service masq caching server (DNS)
|
||||
### END INIT INFO
|
||||
|
||||
NAMED_BIN=/usr/sbin/dnsmasq
|
||||
NAMED_PID=/var/run/dnsmasq.pid
|
||||
NAMED_CONF=/etc/dnsmasq.conf
|
||||
|
||||
if [ ! -x $NAMED_BIN ] ; then
|
||||
echo -n "dnsmasq not installed ! "
|
||||
exit 5
|
||||
fi
|
||||
|
||||
. /etc/rc.status
|
||||
rc_reset
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
echo -n "Starting name service masq caching server "
|
||||
checkproc -p $NAMED_PID $NAMED_BIN
|
||||
if [ $? -eq 0 ] ; then
|
||||
echo -n "- Warning: dnsmasq already running ! "
|
||||
else
|
||||
[ -e $NAMED_PID ] && echo -n "- Warning: $NAMED_PID exists ! "
|
||||
fi
|
||||
startproc -p $NAMED_PID $NAMED_BIN -u nobody
|
||||
rc_status -v
|
||||
;;
|
||||
stop)
|
||||
echo -n "Shutting name service masq caching server "
|
||||
checkproc -p $NAMED_PID $NAMED_BIN
|
||||
[ $? -ne 0 ] && echo -n "- Warning: dnsmasq not running ! "
|
||||
killproc -p $NAMED_PID -TERM $NAMED_BIN
|
||||
rc_status -v
|
||||
;;
|
||||
try-restart)
|
||||
$0 stop && $0 start
|
||||
rc_status
|
||||
;;
|
||||
restart)
|
||||
$0 stop
|
||||
$0 start
|
||||
rc_status
|
||||
;;
|
||||
force-reload)
|
||||
$0 reload
|
||||
rc_status
|
||||
;;
|
||||
reload)
|
||||
echo -n "Reloading name service masq caching server "
|
||||
checkproc -p $NAMED_PID $NAMED_BIN
|
||||
[ $? -ne 0 ] && echo -n "- Warning: dnsmasq not running ! "
|
||||
killproc -p $NAMED_PID -HUP $NAMED_BIN
|
||||
rc_status -v
|
||||
;;
|
||||
status)
|
||||
echo -n "Checking for name service masq caching server "
|
||||
checkproc -p $NAMED_PID $NAMED_BIN
|
||||
rc_status -v
|
||||
;;
|
||||
probe)
|
||||
test $NAMED_CONF -nt $NAMED_PID && echo reload
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {start|stop|status|try-restart|restart|force-reload|reload|probe}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
rc_exit
|
||||
|
||||
14
setup.html
14
setup.html
@@ -78,7 +78,7 @@ by modifying MODIFY_RESOLV_CONF_DYNAMICALLY="no" in <TT>/etc/sysconfig/network/c
|
||||
|
||||
|
||||
<h3>Automatic DNS server configuration with DHCP.</h3>
|
||||
You need to get your DHCP client to write the addresse(s) of the DNS
|
||||
You need to get your DHCP client to write the address(es) of the DNS
|
||||
servers to a file other than <TT>/etc/resolv.conf</TT>. For dhcpcd, the
|
||||
<TT>dhcpcd.exe</TT> script gets run with the addresses of the nameserver(s) in
|
||||
the shell variable <TT>$DNS</TT>. The following bit of shell script
|
||||
@@ -86,8 +86,8 @@ uses that to write a file suitable for dnsmasq.
|
||||
<PRE>
|
||||
|
||||
echo -n >|/etc/dhcpc/resolv.conf
|
||||
dnsservs=${DNS//,/ }
|
||||
for serv in $dnsservs; do
|
||||
dnsservers=${DNS//,/ }
|
||||
for serv in $dnsservers; do
|
||||
echo "nameserver $serv" >>/etc/dhcpc/resolv.conf
|
||||
done
|
||||
|
||||
@@ -125,7 +125,7 @@ address of its ethernet card. For the former to work, a machine needs to know it
|
||||
requests a DHCP lease. For dhcpcd, the -h option specifies this. The
|
||||
names may be anything as far as DHCP is concerned, but dnsmasq adds
|
||||
some limitations. By default the names must no have a domain part, ie
|
||||
they must just be a alphanumeric name, without any dots. This is a
|
||||
they must just be alphanumeric names, without any dots. This is a
|
||||
security feature to stop a machine on your network telling DHCP that
|
||||
its name is "www.microsoft.com" and thereby grabbing traffic which
|
||||
shouldn't go to it. A domain part is only allowed by dnsmasq in DHCP machine names
|
||||
@@ -186,7 +186,7 @@ more than one nameserver just include as many
|
||||
|
||||
<H2>Local domains.</H2>
|
||||
Sometimes people have local domains which they do not want forwarded
|
||||
to upstream servers. This is accomodated by using server options
|
||||
to upstream servers. This is accommodated by using server options
|
||||
without the server IP address. To make things clearer <TT>local</TT>
|
||||
is a synonym for <TT>server</TT>. For example the option
|
||||
<TT>local=/localnet/</TT> ensures that any domain name query which ends in
|
||||
@@ -221,7 +221,7 @@ triggering dial-on-demand internet links.
|
||||
Sending SIGHUP to the dnsmasq process will cause it to empty its cache and
|
||||
then re-load <TT>/etc/hosts</TT> and <TT>/etc/resolv.conf</TT>.
|
||||
<P> Sending SIGUSR1 (killall -10 dnsmasq) to the dnsmasq process will
|
||||
cause to to write cache usage statisticss to the log, typically
|
||||
cause to write cache usage statisticss to the log, typically
|
||||
<TT>/var/log/syslog</TT> or <TT>/var/log/messages</TT>.
|
||||
<P> The <TT>log-queries</TT> option tells dnsmasq to verbosely log the queries
|
||||
it is handling and causes SIGUSR1 to trigger a complete dump of the
|
||||
@@ -229,3 +229,5 @@ contents of the cache to the syslog.
|
||||
|
||||
<P>For a complete listing of options please take a look at the manpage
|
||||
dnsmasq(8).
|
||||
</BODY>
|
||||
</HTML>
|
||||
|
||||
232
src/arp.c
Normal file
232
src/arp.c
Normal file
@@ -0,0 +1,232 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 dated June, 1991, or
|
||||
(at your option) version 3 dated 29 June, 2007.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "dnsmasq.h"
|
||||
|
||||
/* Time between forced re-loads from kernel. */
|
||||
#define INTERVAL 90
|
||||
|
||||
#define ARP_MARK 0
|
||||
#define ARP_FOUND 1 /* Confirmed */
|
||||
#define ARP_NEW 2 /* Newly created */
|
||||
#define ARP_EMPTY 3 /* No MAC addr */
|
||||
|
||||
struct arp_record {
|
||||
unsigned short hwlen, status;
|
||||
int family;
|
||||
unsigned char hwaddr[DHCP_CHADDR_MAX];
|
||||
union all_addr addr;
|
||||
struct arp_record *next;
|
||||
};
|
||||
|
||||
static struct arp_record *arps = NULL, *old = NULL, *freelist = NULL;
|
||||
static time_t last = 0;
|
||||
|
||||
static int filter_mac(int family, void *addrp, char *mac, size_t maclen, void *parmv)
|
||||
{
|
||||
struct arp_record *arp;
|
||||
|
||||
(void)parmv;
|
||||
|
||||
if (maclen > DHCP_CHADDR_MAX)
|
||||
return 1;
|
||||
|
||||
/* Look for existing entry */
|
||||
for (arp = arps; arp; arp = arp->next)
|
||||
{
|
||||
if (family != arp->family || arp->status == ARP_NEW)
|
||||
continue;
|
||||
|
||||
if (family == AF_INET)
|
||||
{
|
||||
if (arp->addr.addr4.s_addr != ((struct in_addr *)addrp)->s_addr)
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!IN6_ARE_ADDR_EQUAL(&arp->addr.addr6, (struct in6_addr *)addrp))
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arp->status == ARP_EMPTY)
|
||||
{
|
||||
/* existing address, was negative. */
|
||||
arp->status = ARP_NEW;
|
||||
arp->hwlen = maclen;
|
||||
memcpy(arp->hwaddr, mac, maclen);
|
||||
}
|
||||
else if (arp->hwlen == maclen && memcmp(arp->hwaddr, mac, maclen) == 0)
|
||||
/* Existing entry matches - confirm. */
|
||||
arp->status = ARP_FOUND;
|
||||
else
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (!arp)
|
||||
{
|
||||
/* New entry */
|
||||
if (freelist)
|
||||
{
|
||||
arp = freelist;
|
||||
freelist = freelist->next;
|
||||
}
|
||||
else if (!(arp = whine_malloc(sizeof(struct arp_record))))
|
||||
return 1;
|
||||
|
||||
arp->next = arps;
|
||||
arps = arp;
|
||||
arp->status = ARP_NEW;
|
||||
arp->hwlen = maclen;
|
||||
arp->family = family;
|
||||
memcpy(arp->hwaddr, mac, maclen);
|
||||
if (family == AF_INET)
|
||||
arp->addr.addr4.s_addr = ((struct in_addr *)addrp)->s_addr;
|
||||
else
|
||||
memcpy(&arp->addr.addr6, addrp, IN6ADDRSZ);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* If in lazy mode, we cache absence of ARP entries. */
|
||||
int find_mac(union mysockaddr *addr, unsigned char *mac, int lazy, time_t now)
|
||||
{
|
||||
struct arp_record *arp, *tmp, **up;
|
||||
int updated = 0;
|
||||
|
||||
again:
|
||||
|
||||
/* If the database is less then INTERVAL old, look in there */
|
||||
if (difftime(now, last) < INTERVAL)
|
||||
{
|
||||
/* addr == NULL -> just make cache up-to-date */
|
||||
if (!addr)
|
||||
return 0;
|
||||
|
||||
for (arp = arps; arp; arp = arp->next)
|
||||
{
|
||||
if (addr->sa.sa_family != arp->family)
|
||||
continue;
|
||||
|
||||
if (arp->family == AF_INET &&
|
||||
arp->addr.addr4.s_addr != addr->in.sin_addr.s_addr)
|
||||
continue;
|
||||
|
||||
if (arp->family == AF_INET6 &&
|
||||
!IN6_ARE_ADDR_EQUAL(&arp->addr.addr6, &addr->in6.sin6_addr))
|
||||
continue;
|
||||
|
||||
/* Only accept positive entries unless in lazy mode. */
|
||||
if (arp->status != ARP_EMPTY || lazy || updated)
|
||||
{
|
||||
if (mac && arp->hwlen != 0)
|
||||
memcpy(mac, arp->hwaddr, arp->hwlen);
|
||||
return arp->hwlen;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Not found, try the kernel */
|
||||
if (!updated)
|
||||
{
|
||||
updated = 1;
|
||||
last = now;
|
||||
|
||||
/* Mark all non-negative entries */
|
||||
for (arp = arps; arp; arp = arp->next)
|
||||
if (arp->status != ARP_EMPTY)
|
||||
arp->status = ARP_MARK;
|
||||
|
||||
iface_enumerate(AF_UNSPEC, NULL, (callback_t){.af_unspec=filter_mac});
|
||||
|
||||
/* Remove all unconfirmed entries to old list. */
|
||||
for (arp = arps, up = &arps; arp; arp = tmp)
|
||||
{
|
||||
tmp = arp->next;
|
||||
|
||||
if (arp->status == ARP_MARK)
|
||||
{
|
||||
*up = arp->next;
|
||||
arp->next = old;
|
||||
old = arp;
|
||||
}
|
||||
else
|
||||
up = &arp->next;
|
||||
}
|
||||
|
||||
goto again;
|
||||
}
|
||||
|
||||
/* record failure, so we don't consult the kernel each time
|
||||
we're asked for this address */
|
||||
if (freelist)
|
||||
{
|
||||
arp = freelist;
|
||||
freelist = freelist->next;
|
||||
}
|
||||
else
|
||||
arp = whine_malloc(sizeof(struct arp_record));
|
||||
|
||||
if (arp)
|
||||
{
|
||||
arp->next = arps;
|
||||
arps = arp;
|
||||
arp->status = ARP_EMPTY;
|
||||
arp->family = addr->sa.sa_family;
|
||||
arp->hwlen = 0;
|
||||
|
||||
if (addr->sa.sa_family == AF_INET)
|
||||
arp->addr.addr4.s_addr = addr->in.sin_addr.s_addr;
|
||||
else
|
||||
memcpy(&arp->addr.addr6, &addr->in6.sin6_addr, IN6ADDRSZ);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int do_arp_script_run(void)
|
||||
{
|
||||
struct arp_record *arp;
|
||||
|
||||
/* Notify any which went, then move to free list */
|
||||
if (old)
|
||||
{
|
||||
#ifdef HAVE_SCRIPT
|
||||
if (option_bool(OPT_SCRIPT_ARP))
|
||||
queue_arp(ACTION_ARP_DEL, old->hwaddr, old->hwlen, old->family, &old->addr);
|
||||
#endif
|
||||
arp = old;
|
||||
old = arp->next;
|
||||
arp->next = freelist;
|
||||
freelist = arp;
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (arp = arps; arp; arp = arp->next)
|
||||
if (arp->status == ARP_NEW)
|
||||
{
|
||||
#ifdef HAVE_SCRIPT
|
||||
if (option_bool(OPT_SCRIPT_ARP))
|
||||
queue_arp(ACTION_ARP, arp->hwaddr, arp->hwlen, arp->family, &arp->addr);
|
||||
#endif
|
||||
arp->status = ARP_FOUND;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
915
src/auth.c
Normal file
915
src/auth.c
Normal file
@@ -0,0 +1,915 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 dated June, 1991, or
|
||||
(at your option) version 3 dated 29 June, 2007.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "dnsmasq.h"
|
||||
|
||||
#ifdef HAVE_AUTH
|
||||
|
||||
static struct addrlist *find_addrlist(struct addrlist *list, int flag, union all_addr *addr_u)
|
||||
{
|
||||
do {
|
||||
if (!(list->flags & ADDRLIST_IPV6))
|
||||
{
|
||||
struct in_addr netmask, addr = addr_u->addr4;
|
||||
|
||||
if (!(flag & F_IPV4))
|
||||
continue;
|
||||
|
||||
netmask.s_addr = htonl(~(in_addr_t)0 << (32 - list->prefixlen));
|
||||
|
||||
if (is_same_net(addr, list->addr.addr4, netmask))
|
||||
return list;
|
||||
}
|
||||
else if (is_same_net6(&(addr_u->addr6), &list->addr.addr6, list->prefixlen))
|
||||
return list;
|
||||
|
||||
} while ((list = list->next));
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct addrlist *find_subnet(struct auth_zone *zone, int flag, union all_addr *addr_u)
|
||||
{
|
||||
if (!zone->subnet)
|
||||
return NULL;
|
||||
|
||||
return find_addrlist(zone->subnet, flag, addr_u);
|
||||
}
|
||||
|
||||
static struct addrlist *find_exclude(struct auth_zone *zone, int flag, union all_addr *addr_u)
|
||||
{
|
||||
if (!zone->exclude)
|
||||
return NULL;
|
||||
|
||||
return find_addrlist(zone->exclude, flag, addr_u);
|
||||
}
|
||||
|
||||
static int filter_zone(struct auth_zone *zone, int flag, union all_addr *addr_u)
|
||||
{
|
||||
if (find_exclude(zone, flag, addr_u))
|
||||
return 0;
|
||||
|
||||
/* No subnets specified, no filter */
|
||||
if (!zone->subnet)
|
||||
return 1;
|
||||
|
||||
return find_subnet(zone, flag, addr_u) != NULL;
|
||||
}
|
||||
|
||||
int in_zone(struct auth_zone *zone, char *name, char **cut)
|
||||
{
|
||||
size_t namelen = strlen(name);
|
||||
size_t domainlen = strlen(zone->domain);
|
||||
|
||||
if (cut)
|
||||
*cut = NULL;
|
||||
|
||||
if (namelen >= domainlen &&
|
||||
hostname_isequal(zone->domain, &name[namelen - domainlen]))
|
||||
{
|
||||
|
||||
if (namelen == domainlen)
|
||||
return 1;
|
||||
|
||||
if (name[namelen - domainlen - 1] == '.')
|
||||
{
|
||||
if (cut)
|
||||
*cut = &name[namelen - domainlen - 1];
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t now,
|
||||
union mysockaddr *peer_addr, int local_query)
|
||||
{
|
||||
char *name = daemon->namebuff;
|
||||
unsigned char *p, *ansp;
|
||||
int qtype, qclass, rc;
|
||||
int nameoffset, axfroffset = 0;
|
||||
int anscount = 0, authcount = 0;
|
||||
struct crec *crecp;
|
||||
int auth = !local_query, trunc = 0, nxdomain = 1, soa = 0, ns = 0, axfr = 0, out_of_zone = 0, notimp = 0;
|
||||
struct auth_zone *zone = NULL;
|
||||
struct addrlist *subnet = NULL;
|
||||
char *cut;
|
||||
struct mx_srv_record *rec, *move, **up;
|
||||
struct txt_record *txt;
|
||||
struct interface_name *intr;
|
||||
struct naptr *na;
|
||||
union all_addr addr;
|
||||
struct cname *a, *candidate;
|
||||
unsigned int wclen;
|
||||
unsigned int log_flags = local_query ? 0 : F_NOERR;
|
||||
|
||||
if (ntohs(header->qdcount) != 1)
|
||||
return 0;
|
||||
|
||||
/* determine end of question section (we put answers there) */
|
||||
if (!(ansp = skip_questions(header, qlen)))
|
||||
return 0; /* bad packet */
|
||||
|
||||
p = (unsigned char *)(header+1);
|
||||
|
||||
if (OPCODE(header) != QUERY)
|
||||
notimp = 1;
|
||||
else
|
||||
{
|
||||
unsigned int flag = 0;
|
||||
int found = 0;
|
||||
int cname_wildcard = 0;
|
||||
|
||||
/* save pointer to name for copying into answers */
|
||||
nameoffset = p - (unsigned char *)header;
|
||||
|
||||
/* now extract name as .-concatenated string into name */
|
||||
if (!extract_name(header, qlen, &p, name, EXTR_NAME_EXTRACT, 4))
|
||||
return 0; /* bad packet */
|
||||
|
||||
GETSHORT(qtype, p);
|
||||
GETSHORT(qclass, p);
|
||||
|
||||
if (qclass != C_IN)
|
||||
{
|
||||
auth = 0;
|
||||
out_of_zone = 1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ((qtype == T_PTR || qtype == T_SOA || qtype == T_NS) &&
|
||||
(flag = in_arpa_name_2_addr(name, &addr)) &&
|
||||
!local_query)
|
||||
{
|
||||
for (zone = daemon->auth_zones; zone; zone = zone->next)
|
||||
if ((subnet = find_subnet(zone, flag, &addr)))
|
||||
break;
|
||||
|
||||
if (!zone)
|
||||
{
|
||||
out_of_zone = 1;
|
||||
auth = 0;
|
||||
goto done;
|
||||
}
|
||||
else if (qtype == T_SOA)
|
||||
soa = 1, found = 1;
|
||||
else if (qtype == T_NS)
|
||||
ns = 1, found = 1;
|
||||
}
|
||||
|
||||
if (qtype == T_PTR && flag)
|
||||
{
|
||||
intr = NULL;
|
||||
|
||||
if (flag == F_IPV4)
|
||||
for (intr = daemon->int_names; intr; intr = intr->next)
|
||||
{
|
||||
struct addrlist *addrlist;
|
||||
|
||||
for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
|
||||
if (!(addrlist->flags & ADDRLIST_IPV6) && addr.addr4.s_addr == addrlist->addr.addr4.s_addr)
|
||||
break;
|
||||
|
||||
if (addrlist)
|
||||
break;
|
||||
else
|
||||
while (intr->next && strcmp(intr->intr, intr->next->intr) == 0)
|
||||
intr = intr->next;
|
||||
}
|
||||
else if (flag == F_IPV6)
|
||||
for (intr = daemon->int_names; intr; intr = intr->next)
|
||||
{
|
||||
struct addrlist *addrlist;
|
||||
|
||||
for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
|
||||
if ((addrlist->flags & ADDRLIST_IPV6) && IN6_ARE_ADDR_EQUAL(&addr.addr6, &addrlist->addr.addr6))
|
||||
break;
|
||||
|
||||
if (addrlist)
|
||||
break;
|
||||
else
|
||||
while (intr->next && strcmp(intr->intr, intr->next->intr) == 0)
|
||||
intr = intr->next;
|
||||
}
|
||||
|
||||
if (intr)
|
||||
{
|
||||
if (local_query || in_zone(zone, intr->name, NULL))
|
||||
{
|
||||
found = 1;
|
||||
log_query(log_flags | flag | F_REVERSE | F_CONFIG, intr->name, &addr, NULL, 0);
|
||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
||||
daemon->auth_ttl, NULL,
|
||||
T_PTR, C_IN, "d", intr->name))
|
||||
anscount++;
|
||||
}
|
||||
}
|
||||
|
||||
if ((crecp = cache_find_by_addr(NULL, &addr, now, flag)))
|
||||
do {
|
||||
strcpy(name, cache_get_name(crecp));
|
||||
|
||||
if (crecp->flags & F_DHCP && !option_bool(OPT_DHCP_FQDN))
|
||||
{
|
||||
char *p = strchr(name, '.');
|
||||
if (p)
|
||||
*p = 0; /* must be bare name */
|
||||
|
||||
/* add external domain */
|
||||
if (zone)
|
||||
{
|
||||
strcat(name, ".");
|
||||
strcat(name, zone->domain);
|
||||
}
|
||||
log_query(log_flags | flag | F_DHCP | F_REVERSE, name, &addr, record_source(crecp->uid), 0);
|
||||
found = 1;
|
||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
||||
daemon->auth_ttl, NULL,
|
||||
T_PTR, C_IN, "d", name))
|
||||
anscount++;
|
||||
}
|
||||
else if (crecp->flags & (F_DHCP | F_HOSTS) && (local_query || in_zone(zone, name, NULL)))
|
||||
{
|
||||
log_query(log_flags | (crecp->flags & ~F_FORWARD), name, &addr, record_source(crecp->uid), 0);
|
||||
found = 1;
|
||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
||||
daemon->auth_ttl, NULL,
|
||||
T_PTR, C_IN, "d", name))
|
||||
anscount++;
|
||||
}
|
||||
else
|
||||
continue;
|
||||
|
||||
} while ((crecp = cache_find_by_addr(crecp, &addr, now, flag)));
|
||||
|
||||
if (!found && is_rev_synth(flag, &addr, name) && (local_query || in_zone(zone, name, NULL)))
|
||||
{
|
||||
log_query(log_flags | F_CONFIG | F_REVERSE | flag, name, &addr, NULL, 0);
|
||||
found = 1;
|
||||
|
||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
||||
daemon->auth_ttl, NULL,
|
||||
T_PTR, C_IN, "d", name))
|
||||
anscount++;
|
||||
}
|
||||
|
||||
if (found)
|
||||
nxdomain = 0;
|
||||
else
|
||||
log_query(log_flags | flag | F_NEG | F_NXDOMAIN | F_REVERSE | (auth ? F_AUTH : 0), NULL, &addr, NULL, 0);
|
||||
|
||||
goto done;
|
||||
}
|
||||
|
||||
cname_restart:
|
||||
if (found)
|
||||
/* NS and SOA .arpa requests have set found above. */
|
||||
cut = NULL;
|
||||
else
|
||||
{
|
||||
for (zone = daemon->auth_zones; zone; zone = zone->next)
|
||||
if (in_zone(zone, name, &cut))
|
||||
break;
|
||||
|
||||
if (!zone)
|
||||
{
|
||||
out_of_zone = 1;
|
||||
auth = 0;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
for (rec = daemon->mxnames; rec; rec = rec->next)
|
||||
if (!rec->issrv && (rc = hostname_issubdomain(name, rec->name)))
|
||||
{
|
||||
nxdomain = 0;
|
||||
|
||||
if (rc == 2 && qtype == T_MX)
|
||||
{
|
||||
found = 1;
|
||||
log_query(log_flags | F_CONFIG | F_RRNAME, name, NULL, "<MX>", 0);
|
||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl,
|
||||
NULL, T_MX, C_IN, "sd", rec->weight, rec->target))
|
||||
anscount++;
|
||||
}
|
||||
}
|
||||
|
||||
for (move = NULL, up = &daemon->mxnames, rec = daemon->mxnames; rec; rec = rec->next)
|
||||
if (rec->issrv && (rc = hostname_issubdomain(name, rec->name)))
|
||||
{
|
||||
nxdomain = 0;
|
||||
|
||||
if (rc == 2 && qtype == T_SRV)
|
||||
{
|
||||
found = 1;
|
||||
log_query(log_flags | F_CONFIG | F_RRNAME, name, NULL, "<SRV>", 0);
|
||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl,
|
||||
NULL, T_SRV, C_IN, "sssd",
|
||||
rec->priority, rec->weight, rec->srvport, rec->target))
|
||||
|
||||
anscount++;
|
||||
}
|
||||
|
||||
/* unlink first SRV record found */
|
||||
if (!move)
|
||||
{
|
||||
move = rec;
|
||||
*up = rec->next;
|
||||
}
|
||||
else
|
||||
up = &rec->next;
|
||||
}
|
||||
else
|
||||
up = &rec->next;
|
||||
|
||||
/* put first SRV record back at the end. */
|
||||
if (move)
|
||||
{
|
||||
*up = move;
|
||||
move->next = NULL;
|
||||
}
|
||||
|
||||
for (txt = daemon->rr; txt; txt = txt->next)
|
||||
if ((rc = hostname_issubdomain(name, txt->name)))
|
||||
{
|
||||
nxdomain = 0;
|
||||
if (rc == 2 && txt->class == qtype)
|
||||
{
|
||||
found = 1;
|
||||
log_query(log_flags | F_CONFIG | F_RRNAME, name, NULL, NULL, txt->class);
|
||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl,
|
||||
NULL, txt->class, C_IN, "t", txt->len, txt->txt))
|
||||
anscount++;
|
||||
}
|
||||
}
|
||||
|
||||
for (txt = daemon->txt; txt; txt = txt->next)
|
||||
if (txt->class == C_IN && (rc = hostname_issubdomain(name, txt->name)))
|
||||
{
|
||||
nxdomain = 0;
|
||||
if (rc == 2 && qtype == T_TXT)
|
||||
{
|
||||
found = 1;
|
||||
log_query(log_flags | F_CONFIG | F_RRNAME, name, NULL, "<TXT>", 0);
|
||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl,
|
||||
NULL, T_TXT, C_IN, "t", txt->len, txt->txt))
|
||||
anscount++;
|
||||
}
|
||||
}
|
||||
|
||||
for (na = daemon->naptr; na; na = na->next)
|
||||
if ((rc = hostname_issubdomain(name, na->name)))
|
||||
{
|
||||
nxdomain = 0;
|
||||
if (rc == 2 && qtype == T_NAPTR)
|
||||
{
|
||||
found = 1;
|
||||
log_query(log_flags | F_CONFIG | F_RRNAME, name, NULL, "<NAPTR>", 0);
|
||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl,
|
||||
NULL, T_NAPTR, C_IN, "sszzzd",
|
||||
na->order, na->pref, na->flags, na->services, na->regexp, na->replace))
|
||||
anscount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (qtype == T_A)
|
||||
flag = F_IPV4;
|
||||
|
||||
if (qtype == T_AAAA)
|
||||
flag = F_IPV6;
|
||||
|
||||
for (intr = daemon->int_names; intr; intr = intr->next)
|
||||
if ((rc = hostname_issubdomain(name, intr->name)))
|
||||
{
|
||||
struct addrlist *addrlist;
|
||||
|
||||
nxdomain = 0;
|
||||
|
||||
if (rc == 2 && flag)
|
||||
for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
|
||||
if (((addrlist->flags & ADDRLIST_IPV6) ? T_AAAA : T_A) == qtype &&
|
||||
(local_query || filter_zone(zone, flag, &addrlist->addr)))
|
||||
{
|
||||
if (addrlist->flags & ADDRLIST_REVONLY)
|
||||
continue;
|
||||
|
||||
found = 1;
|
||||
log_query(log_flags | F_FORWARD | F_CONFIG | flag, name, &addrlist->addr, NULL, 0);
|
||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
||||
daemon->auth_ttl, NULL, qtype, C_IN,
|
||||
qtype == T_A ? "4" : "6", &addrlist->addr))
|
||||
anscount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found && is_name_synthetic(flag, name, &addr) )
|
||||
{
|
||||
nxdomain = 0;
|
||||
|
||||
log_query(log_flags | F_FORWARD | F_CONFIG | flag, name, &addr, NULL, 0);
|
||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
||||
daemon->auth_ttl, NULL, qtype, C_IN, qtype == T_A ? "4" : "6", &addr))
|
||||
anscount++;
|
||||
}
|
||||
|
||||
if (!cut)
|
||||
{
|
||||
nxdomain = 0;
|
||||
|
||||
if (qtype == T_SOA)
|
||||
{
|
||||
auth = soa = 1; /* inhibits auth section */
|
||||
log_query(log_flags | F_RRNAME | F_AUTH, zone->domain, NULL, "<SOA>", 0);
|
||||
}
|
||||
else if (qtype == T_AXFR)
|
||||
{
|
||||
struct iname *peers;
|
||||
|
||||
if (peer_addr->sa.sa_family == AF_INET)
|
||||
peer_addr->in.sin_port = 0;
|
||||
else
|
||||
{
|
||||
peer_addr->in6.sin6_port = 0;
|
||||
peer_addr->in6.sin6_scope_id = 0;
|
||||
}
|
||||
|
||||
for (peers = daemon->auth_peers; peers; peers = peers->next)
|
||||
if (sockaddr_isequal(peer_addr, &peers->addr))
|
||||
break;
|
||||
|
||||
/* Refuse all AXFR unless --auth-sec-servers or auth-peers is set */
|
||||
if ((!daemon->secondary_forward_server && !daemon->auth_peers) ||
|
||||
(daemon->auth_peers && !peers))
|
||||
{
|
||||
if (peer_addr->sa.sa_family == AF_INET)
|
||||
inet_ntop(AF_INET, &peer_addr->in.sin_addr, daemon->addrbuff, ADDRSTRLEN);
|
||||
else
|
||||
inet_ntop(AF_INET6, &peer_addr->in6.sin6_addr, daemon->addrbuff, ADDRSTRLEN);
|
||||
|
||||
my_syslog(LOG_WARNING, _("ignoring zone transfer request from %s"), daemon->addrbuff);
|
||||
return 0;
|
||||
}
|
||||
|
||||
auth = 1;
|
||||
soa = 1; /* inhibits auth section */
|
||||
ns = 1; /* ensure we include NS records! */
|
||||
axfr = 1;
|
||||
axfroffset = nameoffset;
|
||||
log_query(log_flags | F_RRNAME | F_AUTH, zone->domain, NULL, "<AXFR>", 0);
|
||||
}
|
||||
else if (qtype == T_NS)
|
||||
{
|
||||
auth = 1;
|
||||
ns = 1; /* inhibits auth section */
|
||||
log_query(log_flags | F_RRNAME | F_AUTH, zone->domain, NULL, "<NS>", 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (!option_bool(OPT_DHCP_FQDN) && cut)
|
||||
{
|
||||
*cut = 0; /* remove domain part */
|
||||
|
||||
if (!strchr(name, '.') && (crecp = cache_find_by_name(NULL, name, now, F_IPV4 | F_IPV6)))
|
||||
{
|
||||
if (crecp->flags & F_DHCP)
|
||||
do
|
||||
{
|
||||
nxdomain = 0;
|
||||
if ((crecp->flags & flag) &&
|
||||
(local_query || filter_zone(zone, flag, &(crecp->addr))))
|
||||
{
|
||||
*cut = '.'; /* restore domain part */
|
||||
log_query(log_flags | crecp->flags, name, &crecp->addr, record_source(crecp->uid), 0);
|
||||
*cut = 0; /* remove domain part */
|
||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
||||
daemon->auth_ttl, NULL, qtype, C_IN,
|
||||
qtype == T_A ? "4" : "6", &crecp->addr))
|
||||
anscount++;
|
||||
}
|
||||
} while ((crecp = cache_find_by_name(crecp, name, now, F_IPV4 | F_IPV6)));
|
||||
}
|
||||
|
||||
*cut = '.'; /* restore domain part */
|
||||
}
|
||||
|
||||
if ((crecp = cache_find_by_name(NULL, name, now, F_IPV4 | F_IPV6)))
|
||||
{
|
||||
if ((crecp->flags & F_HOSTS) || (((crecp->flags & F_DHCP) && option_bool(OPT_DHCP_FQDN))))
|
||||
do
|
||||
{
|
||||
nxdomain = 0;
|
||||
if ((crecp->flags & flag) && (local_query || filter_zone(zone, flag, &(crecp->addr))))
|
||||
{
|
||||
log_query(log_flags | (crecp->flags & ~F_REVERSE), name, &crecp->addr, record_source(crecp->uid), 0);
|
||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
||||
daemon->auth_ttl, NULL, qtype, C_IN,
|
||||
qtype == T_A ? "4" : "6", &crecp->addr))
|
||||
anscount++;
|
||||
}
|
||||
} while ((crecp = cache_find_by_name(crecp, name, now, F_IPV4 | F_IPV6)));
|
||||
}
|
||||
|
||||
/* Only supply CNAME if no record for any type is known. */
|
||||
if (nxdomain)
|
||||
{
|
||||
/* Check for possible wildcard match against *.domain
|
||||
return length of match, to get longest.
|
||||
Note that if return length of wildcard section, so
|
||||
we match b.simon to _both_ *.simon and b.simon
|
||||
but return a longer (better) match to b.simon.
|
||||
*/
|
||||
for (wclen = 0, candidate = NULL, a = daemon->cnames; a; a = a->next)
|
||||
if (a->alias[0] == '*')
|
||||
{
|
||||
char *test = name;
|
||||
|
||||
while ((test = strchr(test+1, '.')))
|
||||
{
|
||||
if (hostname_isequal(test, &(a->alias[1])))
|
||||
{
|
||||
if (strlen(test) > wclen && !cname_wildcard)
|
||||
{
|
||||
wclen = strlen(test);
|
||||
candidate = a;
|
||||
cname_wildcard = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else if (hostname_isequal(a->alias, name) && strlen(a->alias) > wclen)
|
||||
{
|
||||
/* Simple case, no wildcard */
|
||||
wclen = strlen(a->alias);
|
||||
candidate = a;
|
||||
}
|
||||
|
||||
if (candidate)
|
||||
{
|
||||
log_query(log_flags | F_CONFIG | F_CNAME, name, NULL, NULL, 0);
|
||||
strcpy(name, candidate->target);
|
||||
if (!strchr(name, '.'))
|
||||
{
|
||||
strcat(name, ".");
|
||||
strcat(name, zone->domain);
|
||||
}
|
||||
found = 1;
|
||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
||||
daemon->auth_ttl, &nameoffset,
|
||||
T_CNAME, C_IN, "d", name))
|
||||
anscount++;
|
||||
|
||||
goto cname_restart;
|
||||
}
|
||||
else if (cache_find_non_terminal(name, now))
|
||||
nxdomain = 0;
|
||||
|
||||
log_query(log_flags | flag | F_NEG | (nxdomain ? F_NXDOMAIN : 0) | F_FORWARD | F_AUTH, name, NULL, NULL, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
/* Add auth section */
|
||||
if (auth && zone)
|
||||
{
|
||||
char *authname;
|
||||
int newoffset, offset = 0;
|
||||
|
||||
if (!subnet)
|
||||
authname = zone->domain;
|
||||
else
|
||||
{
|
||||
/* handle NS and SOA for PTR records */
|
||||
|
||||
authname = name;
|
||||
|
||||
if (!(subnet->flags & ADDRLIST_IPV6))
|
||||
{
|
||||
in_addr_t a = ntohl(subnet->addr.addr4.s_addr) >> 8;
|
||||
char *p = name;
|
||||
|
||||
if (subnet->prefixlen >= 24)
|
||||
p += sprintf(p, "%u.", a & 0xff);
|
||||
a = a >> 8;
|
||||
if (subnet->prefixlen >= 16 )
|
||||
p += sprintf(p, "%u.", a & 0xff);
|
||||
a = a >> 8;
|
||||
sprintf(p, "%u.in-addr.arpa", a & 0xff);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
char *p = name;
|
||||
int i;
|
||||
|
||||
for (i = subnet->prefixlen-1; i >= 0; i -= 4)
|
||||
{
|
||||
int dig = ((unsigned char *)&subnet->addr.addr6)[i>>3];
|
||||
p += sprintf(p, "%.1x.", (i>>2) & 1 ? dig & 15 : dig >> 4);
|
||||
}
|
||||
sprintf(p, "ip6.arpa");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* handle NS and SOA in auth section or for explicit queries */
|
||||
newoffset = ansp - (unsigned char *)header;
|
||||
if (((anscount == 0 && !ns) || soa) &&
|
||||
add_resource_record(header, limit, &trunc, 0, &ansp,
|
||||
daemon->auth_ttl, NULL, T_SOA, C_IN, "ddlllll",
|
||||
authname, daemon->authserver, daemon->hostmaster,
|
||||
daemon->soa_sn, daemon->soa_refresh,
|
||||
daemon->soa_retry, daemon->soa_expiry,
|
||||
daemon->auth_ttl))
|
||||
{
|
||||
offset = newoffset;
|
||||
if (soa)
|
||||
anscount++;
|
||||
else
|
||||
authcount++;
|
||||
}
|
||||
|
||||
if (anscount != 0 || ns)
|
||||
{
|
||||
struct name_list *secondary;
|
||||
|
||||
/* Only include the machine running dnsmasq if it's acting as an auth server */
|
||||
if (daemon->authinterface)
|
||||
{
|
||||
newoffset = ansp - (unsigned char *)header;
|
||||
if (add_resource_record(header, limit, &trunc, -offset, &ansp,
|
||||
daemon->auth_ttl, NULL, T_NS, C_IN, "d", offset == 0 ? authname : NULL, daemon->authserver))
|
||||
{
|
||||
if (offset == 0)
|
||||
offset = newoffset;
|
||||
if (ns)
|
||||
anscount++;
|
||||
else
|
||||
authcount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!subnet)
|
||||
for (secondary = daemon->secondary_forward_server; secondary; secondary = secondary->next)
|
||||
if (add_resource_record(header, limit, &trunc, offset, &ansp,
|
||||
daemon->auth_ttl, NULL, T_NS, C_IN, "d", secondary->name))
|
||||
{
|
||||
if (ns)
|
||||
anscount++;
|
||||
else
|
||||
authcount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (axfr)
|
||||
{
|
||||
for (rec = daemon->mxnames; rec; rec = rec->next)
|
||||
if (in_zone(zone, rec->name, &cut))
|
||||
{
|
||||
if (cut)
|
||||
*cut = 0;
|
||||
|
||||
if (rec->issrv)
|
||||
{
|
||||
if (add_resource_record(header, limit, &trunc, -axfroffset, &ansp, daemon->auth_ttl,
|
||||
NULL, T_SRV, C_IN, "sssd", cut ? rec->name : NULL,
|
||||
rec->priority, rec->weight, rec->srvport, rec->target))
|
||||
|
||||
anscount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (add_resource_record(header, limit, &trunc, -axfroffset, &ansp, daemon->auth_ttl,
|
||||
NULL, T_MX, C_IN, "sd", cut ? rec->name : NULL, rec->weight, rec->target))
|
||||
anscount++;
|
||||
}
|
||||
|
||||
/* restore config data */
|
||||
if (cut)
|
||||
*cut = '.';
|
||||
}
|
||||
|
||||
for (txt = daemon->rr; txt; txt = txt->next)
|
||||
if (in_zone(zone, txt->name, &cut))
|
||||
{
|
||||
if (cut)
|
||||
*cut = 0;
|
||||
|
||||
if (add_resource_record(header, limit, &trunc, -axfroffset, &ansp, daemon->auth_ttl,
|
||||
NULL, txt->class, C_IN, "t", cut ? txt->name : NULL, txt->len, txt->txt))
|
||||
anscount++;
|
||||
|
||||
/* restore config data */
|
||||
if (cut)
|
||||
*cut = '.';
|
||||
}
|
||||
|
||||
for (txt = daemon->txt; txt; txt = txt->next)
|
||||
if (txt->class == C_IN && in_zone(zone, txt->name, &cut))
|
||||
{
|
||||
if (cut)
|
||||
*cut = 0;
|
||||
|
||||
if (add_resource_record(header, limit, &trunc, -axfroffset, &ansp, daemon->auth_ttl,
|
||||
NULL, T_TXT, C_IN, "t", cut ? txt->name : NULL, txt->len, txt->txt))
|
||||
anscount++;
|
||||
|
||||
/* restore config data */
|
||||
if (cut)
|
||||
*cut = '.';
|
||||
}
|
||||
|
||||
for (na = daemon->naptr; na; na = na->next)
|
||||
if (in_zone(zone, na->name, &cut))
|
||||
{
|
||||
if (cut)
|
||||
*cut = 0;
|
||||
|
||||
if (add_resource_record(header, limit, &trunc, -axfroffset, &ansp, daemon->auth_ttl,
|
||||
NULL, T_NAPTR, C_IN, "sszzzd", cut ? na->name : NULL,
|
||||
na->order, na->pref, na->flags, na->services, na->regexp, na->replace))
|
||||
anscount++;
|
||||
|
||||
/* restore config data */
|
||||
if (cut)
|
||||
*cut = '.';
|
||||
}
|
||||
|
||||
for (intr = daemon->int_names; intr; intr = intr->next)
|
||||
if (in_zone(zone, intr->name, &cut))
|
||||
{
|
||||
struct addrlist *addrlist;
|
||||
|
||||
if (cut)
|
||||
*cut = 0;
|
||||
|
||||
for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
|
||||
if (!(addrlist->flags & ADDRLIST_IPV6) &&
|
||||
(local_query || filter_zone(zone, F_IPV4, &addrlist->addr)) &&
|
||||
add_resource_record(header, limit, &trunc, -axfroffset, &ansp,
|
||||
daemon->auth_ttl, NULL, T_A, C_IN, "4", cut ? intr->name : NULL, &addrlist->addr))
|
||||
anscount++;
|
||||
|
||||
for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
|
||||
if ((addrlist->flags & ADDRLIST_IPV6) &&
|
||||
(local_query || filter_zone(zone, F_IPV6, &addrlist->addr)) &&
|
||||
add_resource_record(header, limit, &trunc, -axfroffset, &ansp,
|
||||
daemon->auth_ttl, NULL, T_AAAA, C_IN, "6", cut ? intr->name : NULL, &addrlist->addr))
|
||||
anscount++;
|
||||
|
||||
/* restore config data */
|
||||
if (cut)
|
||||
*cut = '.';
|
||||
}
|
||||
|
||||
for (a = daemon->cnames; a; a = a->next)
|
||||
if (in_zone(zone, a->alias, &cut))
|
||||
{
|
||||
strcpy(name, a->target);
|
||||
if (!strchr(name, '.'))
|
||||
{
|
||||
strcat(name, ".");
|
||||
strcat(name, zone->domain);
|
||||
}
|
||||
|
||||
if (cut)
|
||||
*cut = 0;
|
||||
|
||||
if (add_resource_record(header, limit, &trunc, -axfroffset, &ansp,
|
||||
daemon->auth_ttl, NULL,
|
||||
T_CNAME, C_IN, "d", cut ? a->alias : NULL, name))
|
||||
anscount++;
|
||||
}
|
||||
|
||||
cache_enumerate(1);
|
||||
while ((crecp = cache_enumerate(0)))
|
||||
{
|
||||
if ((crecp->flags & (F_IPV4 | F_IPV6)) &&
|
||||
!(crecp->flags & (F_NEG | F_NXDOMAIN)) &&
|
||||
(crecp->flags & F_FORWARD))
|
||||
{
|
||||
if ((crecp->flags & F_DHCP) && !option_bool(OPT_DHCP_FQDN))
|
||||
{
|
||||
char *cache_name = cache_get_name(crecp);
|
||||
if (!strchr(cache_name, '.') &&
|
||||
(local_query || filter_zone(zone, (crecp->flags & (F_IPV6 | F_IPV4)), &(crecp->addr))) &&
|
||||
add_resource_record(header, limit, &trunc, -axfroffset, &ansp,
|
||||
daemon->auth_ttl, NULL, (crecp->flags & F_IPV6) ? T_AAAA : T_A, C_IN,
|
||||
(crecp->flags & F_IPV4) ? "4" : "6", cache_name, &crecp->addr))
|
||||
anscount++;
|
||||
}
|
||||
|
||||
if ((crecp->flags & F_HOSTS) || (((crecp->flags & F_DHCP) && option_bool(OPT_DHCP_FQDN))))
|
||||
{
|
||||
strcpy(name, cache_get_name(crecp));
|
||||
if (in_zone(zone, name, &cut) &&
|
||||
(local_query || filter_zone(zone, (crecp->flags & (F_IPV6 | F_IPV4)), &(crecp->addr))))
|
||||
{
|
||||
if (cut)
|
||||
*cut = 0;
|
||||
|
||||
if (add_resource_record(header, limit, &trunc, -axfroffset, &ansp,
|
||||
daemon->auth_ttl, NULL, (crecp->flags & F_IPV6) ? T_AAAA : T_A, C_IN,
|
||||
(crecp->flags & F_IPV4) ? "4" : "6", cut ? name : NULL, &crecp->addr))
|
||||
anscount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* repeat SOA as last record */
|
||||
if (add_resource_record(header, limit, &trunc, axfroffset, &ansp,
|
||||
daemon->auth_ttl, NULL, T_SOA, C_IN, "ddlllll",
|
||||
daemon->authserver, daemon->hostmaster,
|
||||
daemon->soa_sn, daemon->soa_refresh,
|
||||
daemon->soa_retry, daemon->soa_expiry,
|
||||
daemon->auth_ttl))
|
||||
anscount++;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* done all questions, set up header and return length of result */
|
||||
/* clear authoritative and truncated flags, set QR flag */
|
||||
header->hb3 = (header->hb3 & ~(HB3_AA | HB3_TC)) | HB3_QR;
|
||||
|
||||
if (local_query)
|
||||
{
|
||||
/* set RA flag */
|
||||
header->hb4 |= HB4_RA;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* clear RA flag */
|
||||
header->hb4 &= ~HB4_RA;
|
||||
}
|
||||
|
||||
/* data is never DNSSEC signed. */
|
||||
header->hb4 &= ~HB4_AD;
|
||||
|
||||
/* authoritative */
|
||||
if (auth)
|
||||
header->hb3 |= HB3_AA;
|
||||
|
||||
/* truncation */
|
||||
if (trunc)
|
||||
{
|
||||
header->hb3 |= HB3_TC;
|
||||
if (!(ansp = skip_questions(header, qlen)))
|
||||
return 0; /* bad packet */
|
||||
anscount = authcount = 0;
|
||||
log_query(log_flags | F_AUTH, "reply", NULL, "truncated", 0);
|
||||
}
|
||||
|
||||
if ((auth || local_query) && nxdomain)
|
||||
SET_RCODE(header, NXDOMAIN);
|
||||
else
|
||||
SET_RCODE(header, NOERROR); /* no error */
|
||||
|
||||
header->ancount = htons(anscount);
|
||||
header->nscount = htons(authcount);
|
||||
header->arcount = htons(0);
|
||||
|
||||
if ((!local_query && out_of_zone) || notimp)
|
||||
{
|
||||
if (out_of_zone)
|
||||
{
|
||||
addr.log.rcode = REFUSED;
|
||||
addr.log.ede = EDE_NOT_AUTH;
|
||||
}
|
||||
else
|
||||
{
|
||||
addr.log.rcode = NOTIMP;
|
||||
addr.log.ede = EDE_UNSET;
|
||||
}
|
||||
|
||||
SET_RCODE(header, addr.log.rcode);
|
||||
header->ancount = htons(0);
|
||||
header->nscount = htons(0);
|
||||
log_query(log_flags | F_UPSTREAM | F_RCODE, "error", &addr, NULL, 0);
|
||||
return resize_packet(header, ansp - (unsigned char *)header, NULL, 0);
|
||||
}
|
||||
|
||||
return ansp - (unsigned char *)header;
|
||||
}
|
||||
|
||||
#endif
|
||||
239
src/blockdata.c
Normal file
239
src/blockdata.c
Normal file
@@ -0,0 +1,239 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 dated June, 1991, or
|
||||
(at your option) version 3 dated 29 June, 2007.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "dnsmasq.h"
|
||||
|
||||
static struct blockdata *keyblock_free;
|
||||
static unsigned int blockdata_count, blockdata_hwm, blockdata_alloced;
|
||||
|
||||
static void add_blocks(int n)
|
||||
{
|
||||
struct blockdata *new = whine_malloc(n * sizeof(struct blockdata));
|
||||
|
||||
if (new)
|
||||
{
|
||||
int i;
|
||||
|
||||
new[n-1].next = keyblock_free;
|
||||
keyblock_free = new;
|
||||
|
||||
for (i = 0; i < n - 1; i++)
|
||||
new[i].next = &new[i+1];
|
||||
|
||||
blockdata_alloced += n;
|
||||
}
|
||||
}
|
||||
|
||||
/* Preallocate some blocks, proportional to cachesize, to reduce heap fragmentation. */
|
||||
void blockdata_init(void)
|
||||
{
|
||||
keyblock_free = NULL;
|
||||
blockdata_alloced = 0;
|
||||
blockdata_count = 0;
|
||||
blockdata_hwm = 0;
|
||||
|
||||
/* Note that daemon->cachesize is enforced to have non-zero size if OPT_DNSSEC_VALID is set */
|
||||
if (option_bool(OPT_DNSSEC_VALID))
|
||||
add_blocks(daemon->cachesize);
|
||||
}
|
||||
|
||||
void blockdata_report(void)
|
||||
{
|
||||
my_syslog(LOG_INFO, _("pool memory in use %zu, max %zu, allocated %zu"),
|
||||
blockdata_count * sizeof(struct blockdata),
|
||||
blockdata_hwm * sizeof(struct blockdata),
|
||||
blockdata_alloced * sizeof(struct blockdata));
|
||||
}
|
||||
|
||||
static struct blockdata *new_block(void)
|
||||
{
|
||||
struct blockdata *block;
|
||||
|
||||
if (!keyblock_free)
|
||||
add_blocks(50);
|
||||
|
||||
if (keyblock_free)
|
||||
{
|
||||
block = keyblock_free;
|
||||
keyblock_free = block->next;
|
||||
blockdata_count++;
|
||||
if (blockdata_hwm < blockdata_count)
|
||||
blockdata_hwm = blockdata_count;
|
||||
block->next = NULL;
|
||||
return block;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct blockdata *blockdata_alloc_real(int fd, char *data, size_t len)
|
||||
{
|
||||
struct blockdata *block, *ret = NULL;
|
||||
struct blockdata **prev = &ret;
|
||||
size_t blen;
|
||||
|
||||
do
|
||||
{
|
||||
if (!(block = new_block()))
|
||||
{
|
||||
/* failed to alloc, free partial chain */
|
||||
blockdata_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((blen = len > KEYBLOCK_LEN ? KEYBLOCK_LEN : len) > 0)
|
||||
{
|
||||
if (data)
|
||||
{
|
||||
memcpy(block->key, data, blen);
|
||||
data += blen;
|
||||
}
|
||||
else if (!read_write(fd, block->key, blen, RW_READ))
|
||||
{
|
||||
/* failed read free partial chain */
|
||||
blockdata_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
len -= blen;
|
||||
*prev = block;
|
||||
prev = &block->next;
|
||||
} while (len != 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct blockdata *blockdata_alloc(char *data, size_t len)
|
||||
{
|
||||
return blockdata_alloc_real(0, data, len);
|
||||
}
|
||||
|
||||
/* Add data to the end of the block.
|
||||
newlen is length of new data, NOT total new length.
|
||||
Use blockdata_alloc(NULL, 0) to make empty block to add to. */
|
||||
int blockdata_expand(struct blockdata *block, size_t oldlen, char *data, size_t newlen)
|
||||
{
|
||||
struct blockdata *b;
|
||||
|
||||
/* find size of current final block */
|
||||
for (b = block; oldlen > KEYBLOCK_LEN && b; b = b->next, oldlen -= KEYBLOCK_LEN);
|
||||
|
||||
/* chain to short for length, something is broken */
|
||||
if (oldlen > KEYBLOCK_LEN)
|
||||
{
|
||||
blockdata_free(block);
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
struct blockdata *new;
|
||||
size_t blocksize = KEYBLOCK_LEN - oldlen;
|
||||
size_t size = (newlen <= blocksize) ? newlen : blocksize;
|
||||
|
||||
if (size != 0)
|
||||
{
|
||||
memcpy(&b->key[oldlen], data, size);
|
||||
data += size;
|
||||
newlen -= size;
|
||||
}
|
||||
|
||||
/* full blocks from now on. */
|
||||
oldlen = 0;
|
||||
|
||||
if (newlen == 0)
|
||||
break;
|
||||
|
||||
if ((new = new_block()))
|
||||
{
|
||||
b->next = new;
|
||||
b = new;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* failed to alloc, free partial chain */
|
||||
blockdata_free(block);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void blockdata_free(struct blockdata *blocks)
|
||||
{
|
||||
struct blockdata *tmp;
|
||||
|
||||
if (blocks)
|
||||
{
|
||||
for (tmp = blocks; tmp->next; tmp = tmp->next)
|
||||
blockdata_count--;
|
||||
tmp->next = keyblock_free;
|
||||
keyblock_free = blocks;
|
||||
blockdata_count--;
|
||||
}
|
||||
}
|
||||
|
||||
/* if data == NULL, return pointer to static block of sufficient size */
|
||||
void *blockdata_retrieve(struct blockdata *block, size_t len, void *data)
|
||||
{
|
||||
size_t blen;
|
||||
struct blockdata *b;
|
||||
uint8_t *new, *d;
|
||||
|
||||
static unsigned int buff_len = 0;
|
||||
static unsigned char *buff = NULL;
|
||||
|
||||
if (!data)
|
||||
{
|
||||
if (len > buff_len)
|
||||
{
|
||||
if (!(new = whine_malloc(len)))
|
||||
return NULL;
|
||||
if (buff)
|
||||
free(buff);
|
||||
buff = new;
|
||||
}
|
||||
data = buff;
|
||||
}
|
||||
|
||||
for (d = data, b = block; len > 0 && b; b = b->next)
|
||||
{
|
||||
blen = len > KEYBLOCK_LEN ? KEYBLOCK_LEN : len;
|
||||
memcpy(d, b->key, blen);
|
||||
d += blen;
|
||||
len -= blen;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
void blockdata_write(struct blockdata *block, size_t len, int fd)
|
||||
{
|
||||
for (; len > 0 && block; block = block->next)
|
||||
{
|
||||
size_t blen = len > KEYBLOCK_LEN ? KEYBLOCK_LEN : len;
|
||||
read_write(fd, block->key, blen, RW_WRITE);
|
||||
len -= blen;
|
||||
}
|
||||
}
|
||||
|
||||
struct blockdata *blockdata_read(int fd, size_t len)
|
||||
{
|
||||
return blockdata_alloc_real(fd, NULL, len);
|
||||
}
|
||||
521
src/bpf.c
521
src/bpf.c
@@ -1,61 +1,266 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2006 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 dated June, 1991.
|
||||
|
||||
the Free Software Foundation; version 2 dated June, 1991, or
|
||||
(at your option) version 3 dated 29 June, 2007.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "dnsmasq.h"
|
||||
|
||||
#ifndef HAVE_LINUX_NETWORK
|
||||
#if defined(HAVE_BSD_NETWORK) || defined(HAVE_SOLARIS_NETWORK)
|
||||
#include <ifaddrs.h>
|
||||
|
||||
#include <sys/param.h>
|
||||
#if defined(HAVE_BSD_NETWORK) && !defined(__APPLE__)
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
#include <net/if.h>
|
||||
#include <net/route.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <netinet/if_ether.h>
|
||||
#if defined(__FreeBSD__)
|
||||
# include <net/if_var.h>
|
||||
#endif
|
||||
#include <netinet/in_var.h>
|
||||
#include <netinet6/in6_var.h>
|
||||
|
||||
#ifndef SA_SIZE
|
||||
#define SA_SIZE(sa) \
|
||||
( (!(sa) || ((struct sockaddr *)(sa))->sa_len == 0) ? \
|
||||
sizeof(long) : \
|
||||
1 + ( (((struct sockaddr *)(sa))->sa_len - 1) | (sizeof(long) - 1) ) )
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_BSD_NETWORK
|
||||
static int del_family = 0;
|
||||
static union all_addr del_addr;
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_BSD_NETWORK) && !defined(__APPLE__)
|
||||
|
||||
int arp_enumerate(void *parm, callback_t callback)
|
||||
{
|
||||
int mib[6];
|
||||
size_t needed;
|
||||
char *next;
|
||||
struct rt_msghdr *rtm;
|
||||
struct sockaddr_inarp *sin2;
|
||||
struct sockaddr_dl *sdl;
|
||||
struct iovec buff;
|
||||
int rc;
|
||||
|
||||
buff.iov_base = NULL;
|
||||
buff.iov_len = 0;
|
||||
|
||||
mib[0] = CTL_NET;
|
||||
mib[1] = PF_ROUTE;
|
||||
mib[2] = 0;
|
||||
mib[3] = AF_INET;
|
||||
mib[4] = NET_RT_FLAGS;
|
||||
#ifdef RTF_LLINFO
|
||||
mib[5] = RTF_LLINFO;
|
||||
#else
|
||||
mib[5] = 0;
|
||||
#endif
|
||||
if (sysctl(mib, 6, NULL, &needed, NULL, 0) == -1 || needed == 0)
|
||||
return 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (!expand_buf(&buff, needed))
|
||||
return 0;
|
||||
if ((rc = sysctl(mib, 6, buff.iov_base, &needed, NULL, 0)) == 0 ||
|
||||
errno != ENOMEM)
|
||||
break;
|
||||
needed += needed / 8;
|
||||
}
|
||||
if (rc == -1)
|
||||
return 0;
|
||||
|
||||
for (next = buff.iov_base ; next < (char *)buff.iov_base + needed; next += rtm->rtm_msglen)
|
||||
{
|
||||
rtm = (struct rt_msghdr *)next;
|
||||
sin2 = (struct sockaddr_inarp *)(rtm + 1);
|
||||
sdl = (struct sockaddr_dl *)((char *)sin2 + SA_SIZE(sin2));
|
||||
if (!callback.af_unspec(AF_INET, &sin2->sin_addr, LLADDR(sdl), sdl->sdl_alen, parm))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif /* defined(HAVE_BSD_NETWORK) && !defined(__APPLE__) */
|
||||
|
||||
|
||||
int iface_enumerate(int family, void *parm, callback_t callback)
|
||||
{
|
||||
struct ifaddrs *head, *addrs;
|
||||
int errsave, fd = -1, ret = 0;
|
||||
|
||||
if (family == AF_UNSPEC)
|
||||
#if defined(HAVE_BSD_NETWORK) && !defined(__APPLE__)
|
||||
return arp_enumerate(parm, callback);
|
||||
#else
|
||||
return 0; /* need code for Solaris and MacOS*/
|
||||
#endif
|
||||
|
||||
/* AF_LINK doesn't exist in Linux, so we can't use it in our API */
|
||||
if (family == AF_LOCAL)
|
||||
family = AF_LINK;
|
||||
|
||||
if (getifaddrs(&head) == -1)
|
||||
return 0;
|
||||
|
||||
#if defined(HAVE_BSD_NETWORK)
|
||||
if (family == AF_INET6)
|
||||
fd = socket(PF_INET6, SOCK_DGRAM, 0);
|
||||
#endif
|
||||
|
||||
for (addrs = head; addrs; addrs = addrs->ifa_next)
|
||||
{
|
||||
int iface_index = if_nametoindex(addrs->ifa_name);
|
||||
|
||||
if (iface_index == 0 || !addrs->ifa_addr ||
|
||||
addrs->ifa_addr->sa_family != family ||
|
||||
(!addrs->ifa_netmask && family != AF_LINK))
|
||||
continue;
|
||||
|
||||
if (family == AF_INET)
|
||||
{
|
||||
struct in_addr addr, netmask, broadcast;
|
||||
addr = ((struct sockaddr_in *) addrs->ifa_addr)->sin_addr;
|
||||
#ifdef HAVE_BSD_NETWORK
|
||||
if (del_family == AF_INET && del_addr.addr4.s_addr == addr.s_addr)
|
||||
continue;
|
||||
#endif
|
||||
netmask = ((struct sockaddr_in *) addrs->ifa_netmask)->sin_addr;
|
||||
if (addrs->ifa_broadaddr)
|
||||
broadcast = ((struct sockaddr_in *) addrs->ifa_broadaddr)->sin_addr;
|
||||
else
|
||||
broadcast.s_addr = 0;
|
||||
if (!callback.af_inet(addr, iface_index, NULL, netmask, broadcast, parm))
|
||||
goto err;
|
||||
}
|
||||
else if (family == AF_INET6)
|
||||
{
|
||||
struct in6_addr *addr = &((struct sockaddr_in6 *) addrs->ifa_addr)->sin6_addr;
|
||||
unsigned char *netmask = (unsigned char *) &((struct sockaddr_in6 *) addrs->ifa_netmask)->sin6_addr;
|
||||
int scope_id = ((struct sockaddr_in6 *) addrs->ifa_addr)->sin6_scope_id;
|
||||
int i, j, prefix = 0;
|
||||
u32 valid = 0xffffffff, preferred = 0xffffffff;
|
||||
int flags = 0;
|
||||
#ifdef HAVE_BSD_NETWORK
|
||||
if (del_family == AF_INET6 && IN6_ARE_ADDR_EQUAL(&del_addr.addr6, addr))
|
||||
continue;
|
||||
#endif
|
||||
#if defined(HAVE_BSD_NETWORK) && !defined(__APPLE__)
|
||||
struct in6_ifreq ifr6;
|
||||
|
||||
memset(&ifr6, 0, sizeof(ifr6));
|
||||
safe_strncpy(ifr6.ifr_name, addrs->ifa_name, sizeof(ifr6.ifr_name));
|
||||
|
||||
ifr6.ifr_addr = *((struct sockaddr_in6 *) addrs->ifa_addr);
|
||||
if (fd != -1 && ioctl(fd, SIOCGIFAFLAG_IN6, &ifr6) != -1)
|
||||
{
|
||||
if (ifr6.ifr_ifru.ifru_flags6 & IN6_IFF_TENTATIVE)
|
||||
flags |= IFACE_TENTATIVE;
|
||||
|
||||
if (ifr6.ifr_ifru.ifru_flags6 & IN6_IFF_DEPRECATED)
|
||||
flags |= IFACE_DEPRECATED;
|
||||
|
||||
#ifdef IN6_IFF_TEMPORARY
|
||||
if (!(ifr6.ifr_ifru.ifru_flags6 & (IN6_IFF_AUTOCONF | IN6_IFF_TEMPORARY)))
|
||||
flags |= IFACE_PERMANENT;
|
||||
#endif
|
||||
|
||||
#ifdef IN6_IFF_PRIVACY
|
||||
if (!(ifr6.ifr_ifru.ifru_flags6 & (IN6_IFF_AUTOCONF | IN6_IFF_PRIVACY)))
|
||||
flags |= IFACE_PERMANENT;
|
||||
#endif
|
||||
}
|
||||
|
||||
ifr6.ifr_addr = *((struct sockaddr_in6 *) addrs->ifa_addr);
|
||||
if (fd != -1 && ioctl(fd, SIOCGIFALIFETIME_IN6, &ifr6) != -1)
|
||||
{
|
||||
valid = ifr6.ifr_ifru.ifru_lifetime.ia6t_vltime;
|
||||
preferred = ifr6.ifr_ifru.ifru_lifetime.ia6t_pltime;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = 0; i < IN6ADDRSZ; i++, prefix += 8)
|
||||
if (netmask[i] != 0xff)
|
||||
break;
|
||||
|
||||
if (i != IN6ADDRSZ && netmask[i])
|
||||
for (j = 7; j > 0; j--, prefix++)
|
||||
if ((netmask[i] & (1 << j)) == 0)
|
||||
break;
|
||||
|
||||
/* voodoo to clear interface field in address */
|
||||
if (!option_bool(OPT_NOWILD) && IN6_IS_ADDR_LINKLOCAL(addr))
|
||||
{
|
||||
addr->s6_addr[2] = 0;
|
||||
addr->s6_addr[3] = 0;
|
||||
}
|
||||
|
||||
if (!callback.af_inet6(addr, prefix, scope_id, iface_index, flags,
|
||||
(unsigned int) preferred, (unsigned int)valid, parm))
|
||||
goto err;
|
||||
}
|
||||
|
||||
#ifdef HAVE_DHCP6
|
||||
else if (family == AF_LINK)
|
||||
{
|
||||
/* Assume ethernet again here */
|
||||
struct sockaddr_dl *sdl = (struct sockaddr_dl *) addrs->ifa_addr;
|
||||
if (sdl->sdl_alen != 0 &&
|
||||
!callback.af_local(iface_index, ARPHRD_ETHER, LLADDR(sdl), sdl->sdl_alen, parm))
|
||||
goto err;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
errsave = errno;
|
||||
freeifaddrs(head);
|
||||
if (fd != -1)
|
||||
close(fd);
|
||||
errno = errsave;
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* defined(HAVE_BSD_NETWORK) || defined(HAVE_SOLARIS_NETWORK) */
|
||||
|
||||
|
||||
#if defined(HAVE_BSD_NETWORK) && defined(HAVE_DHCP)
|
||||
#include <net/bpf.h>
|
||||
|
||||
static struct iovec ifconf = {
|
||||
.iov_base = NULL,
|
||||
.iov_len = 0
|
||||
};
|
||||
|
||||
static struct iovec ifreq = {
|
||||
.iov_base = NULL,
|
||||
.iov_len = 0
|
||||
};
|
||||
|
||||
struct header {
|
||||
struct ether_header ether;
|
||||
struct ip ip;
|
||||
struct udphdr {
|
||||
u16 uh_sport; /* source port */
|
||||
u16 uh_dport; /* destination port */
|
||||
u16 uh_ulen; /* udp length */
|
||||
u16 uh_sum; /* udp checksum */
|
||||
} udp;
|
||||
};
|
||||
|
||||
void init_bpf(struct daemon *daemon)
|
||||
void init_bpf(void)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
/* useful size which happens to be sufficient */
|
||||
if (expand_buf(&ifreq, sizeof(struct ifreq)))
|
||||
{
|
||||
sprintf(ifreq.iov_base, "/dev/bpf%d", i++);
|
||||
if ((daemon->dhcp_raw_fd = open(ifreq.iov_base, O_RDWR, 0)) != -1)
|
||||
return;
|
||||
}
|
||||
sprintf(daemon->dhcp_buff, "/dev/bpf%d", i++);
|
||||
if ((daemon->dhcp_raw_fd = open(daemon->dhcp_buff, O_RDWR, 0)) != -1)
|
||||
return;
|
||||
|
||||
if (errno != EBUSY)
|
||||
die(_("cannot create DHCP BPF socket: %s"), NULL);
|
||||
die(_("cannot create DHCP BPF socket: %s"), NULL, EC_BADNET);
|
||||
}
|
||||
}
|
||||
|
||||
void send_via_bpf(struct daemon *daemon, struct dhcp_packet *mess, size_t len,
|
||||
void send_via_bpf(struct dhcp_packet *mess, size_t len,
|
||||
struct in_addr iface_addr, struct ifreq *ifr)
|
||||
{
|
||||
/* Hairy stuff, packet either has to go to the
|
||||
@@ -64,15 +269,23 @@ void send_via_bpf(struct daemon *daemon, struct dhcp_packet *mess, size_t len,
|
||||
Build the packet by steam, and send directly, bypassing
|
||||
the kernel IP stack */
|
||||
|
||||
struct header header;
|
||||
struct ether_header ether;
|
||||
struct ip ip;
|
||||
struct udphdr {
|
||||
u16 uh_sport; /* source port */
|
||||
u16 uh_dport; /* destination port */
|
||||
u16 uh_ulen; /* udp length */
|
||||
u16 uh_sum; /* udp checksum */
|
||||
} udp;
|
||||
|
||||
u32 i, sum;
|
||||
struct iovec iov[2];
|
||||
struct iovec iov[4];
|
||||
|
||||
/* Only know how to do ethernet on *BSD */
|
||||
if (mess->htype != ARPHRD_ETHER || mess->hlen != ETHER_ADDR_LEN)
|
||||
{
|
||||
syslog(LOG_WARNING, _("DHCP request for unsupported hardware type (%d) received on %s"),
|
||||
mess->htype, ifr->ifr_name);
|
||||
my_syslog(MS_DHCP | LOG_WARNING, _("DHCP request for unsupported hardware type (%d) received on %s"),
|
||||
mess->htype, ifr->ifr_name);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -80,156 +293,148 @@ void send_via_bpf(struct daemon *daemon, struct dhcp_packet *mess, size_t len,
|
||||
if (ioctl(daemon->dhcpfd, SIOCGIFADDR, ifr) < 0)
|
||||
return;
|
||||
|
||||
memcpy(header.ether.ether_shost, LLADDR((struct sockaddr_dl *)&ifr->ifr_addr), ETHER_ADDR_LEN);
|
||||
header.ether.ether_type = htons(ETHERTYPE_IP);
|
||||
memcpy(ether.ether_shost, LLADDR((struct sockaddr_dl *)&ifr->ifr_addr), ETHER_ADDR_LEN);
|
||||
ether.ether_type = htons(ETHERTYPE_IP);
|
||||
|
||||
if (ntohs(mess->flags) & 0x8000)
|
||||
{
|
||||
memset(header.ether.ether_dhost, 255, ETHER_ADDR_LEN);
|
||||
header.ip.ip_dst.s_addr = INADDR_BROADCAST;
|
||||
memset(ether.ether_dhost, 255, ETHER_ADDR_LEN);
|
||||
ip.ip_dst.s_addr = INADDR_BROADCAST;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(header.ether.ether_dhost, mess->chaddr, ETHER_ADDR_LEN);
|
||||
header.ip.ip_dst.s_addr = mess->yiaddr.s_addr;
|
||||
memcpy(ether.ether_dhost, mess->chaddr, ETHER_ADDR_LEN);
|
||||
ip.ip_dst.s_addr = mess->yiaddr.s_addr;
|
||||
}
|
||||
|
||||
header.ip.ip_p = IPPROTO_UDP;
|
||||
header.ip.ip_src.s_addr = iface_addr.s_addr;
|
||||
header.ip.ip_len = htons(sizeof(struct ip) +
|
||||
sizeof(struct udphdr) +
|
||||
len) ;
|
||||
header.ip.ip_hl = sizeof(struct ip) / 4;
|
||||
header.ip.ip_v = IPVERSION;
|
||||
header.ip.ip_tos = 0;
|
||||
header.ip.ip_id = htons(0);
|
||||
header.ip.ip_off = htons(0x4000); /* don't fragment */
|
||||
header.ip.ip_ttl = IPDEFTTL;
|
||||
header.ip.ip_sum = 0;
|
||||
ip.ip_p = IPPROTO_UDP;
|
||||
ip.ip_src.s_addr = iface_addr.s_addr;
|
||||
ip.ip_len = htons(sizeof(struct ip) +
|
||||
sizeof(struct udphdr) +
|
||||
len) ;
|
||||
ip.ip_hl = sizeof(struct ip) / 4;
|
||||
ip.ip_v = IPVERSION;
|
||||
ip.ip_tos = 0;
|
||||
ip.ip_id = htons(0);
|
||||
ip.ip_off = htons(0x4000); /* don't fragment */
|
||||
ip.ip_ttl = IPDEFTTL;
|
||||
ip.ip_sum = 0;
|
||||
for (sum = 0, i = 0; i < sizeof(struct ip) / 2; i++)
|
||||
sum += ((u16 *)&header.ip)[i];
|
||||
sum += ((u16 *)&ip)[i];
|
||||
while (sum>>16)
|
||||
sum = (sum & 0xffff) + (sum >> 16);
|
||||
header.ip.ip_sum = (sum == 0xffff) ? sum : ~sum;
|
||||
ip.ip_sum = (sum == 0xffff) ? sum : ~sum;
|
||||
|
||||
header.udp.uh_sport = htons(DHCP_SERVER_PORT);
|
||||
header.udp.uh_dport = htons(DHCP_CLIENT_PORT);
|
||||
udp.uh_sport = htons(daemon->dhcp_server_port);
|
||||
udp.uh_dport = htons(daemon->dhcp_client_port);
|
||||
if (len & 1)
|
||||
((char *)mess)[len] = 0; /* for checksum, in case length is odd. */
|
||||
header.udp.uh_sum = 0;
|
||||
header.udp.uh_ulen = sum = htons(sizeof(struct udphdr) + len);
|
||||
udp.uh_sum = 0;
|
||||
udp.uh_ulen = sum = htons(sizeof(struct udphdr) + len);
|
||||
sum += htons(IPPROTO_UDP);
|
||||
for (i = 0; i < 4; i++)
|
||||
sum += ((u16 *)&header.ip.ip_src)[i];
|
||||
sum += ip.ip_src.s_addr & 0xffff;
|
||||
sum += (ip.ip_src.s_addr >> 16) & 0xffff;
|
||||
sum += ip.ip_dst.s_addr & 0xffff;
|
||||
sum += (ip.ip_dst.s_addr >> 16) & 0xffff;
|
||||
for (i = 0; i < sizeof(struct udphdr)/2; i++)
|
||||
sum += ((u16 *)&header.udp)[i];
|
||||
sum += ((u16 *)&udp)[i];
|
||||
for (i = 0; i < (len + 1) / 2; i++)
|
||||
sum += ((u16 *)mess)[i];
|
||||
while (sum>>16)
|
||||
sum = (sum & 0xffff) + (sum >> 16);
|
||||
header.udp.uh_sum = (sum == 0xffff) ? sum : ~sum;
|
||||
udp.uh_sum = (sum == 0xffff) ? sum : ~sum;
|
||||
|
||||
ioctl(daemon->dhcp_raw_fd, BIOCSETIF, ifr);
|
||||
|
||||
iov[0].iov_base = &header;
|
||||
iov[0].iov_len = sizeof(struct header);
|
||||
iov[1].iov_base = mess;
|
||||
iov[1].iov_len = len;
|
||||
while (writev(daemon->dhcp_raw_fd, iov, 2) == -1 && retry_send());
|
||||
iov[0].iov_base = ðer;
|
||||
iov[0].iov_len = sizeof(ether);
|
||||
iov[1].iov_base = &ip;
|
||||
iov[1].iov_len = sizeof(ip);
|
||||
iov[2].iov_base = &udp;
|
||||
iov[2].iov_len = sizeof(udp);
|
||||
iov[3].iov_base = mess;
|
||||
iov[3].iov_len = len;
|
||||
|
||||
while (retry_send(writev(daemon->dhcp_raw_fd, iov, 4)));
|
||||
}
|
||||
|
||||
int iface_enumerate(struct daemon *daemon, void *parm, int (*ipv4_callback)(), int (*ipv6_callback)())
|
||||
#endif /* defined(HAVE_BSD_NETWORK) && defined(HAVE_DHCP) */
|
||||
|
||||
|
||||
#ifdef HAVE_BSD_NETWORK
|
||||
|
||||
void route_init(void)
|
||||
{
|
||||
char *ptr;
|
||||
struct ifreq *ifr;
|
||||
struct ifconf ifc;
|
||||
int fd, errsav, ret = 0;
|
||||
int lastlen = 0;
|
||||
size_t len;
|
||||
/* AF_UNSPEC: all addr families */
|
||||
daemon->routefd = socket(PF_ROUTE, SOCK_RAW, AF_UNSPEC);
|
||||
|
||||
if ((fd = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
|
||||
return 0;
|
||||
|
||||
for (len = 0; ; len += 10*sizeof(struct ifreq))
|
||||
{
|
||||
if (!expand_buf(&ifconf, len))
|
||||
goto err;
|
||||
if (daemon->routefd == -1 || !fix_fd(daemon->routefd))
|
||||
die(_("cannot create PF_ROUTE socket: %s"), NULL, EC_BADNET);
|
||||
}
|
||||
|
||||
ifc.ifc_len = len;
|
||||
ifc.ifc_buf = ifconf.iov_base;
|
||||
void route_sock(void)
|
||||
{
|
||||
struct if_msghdr *msg;
|
||||
int rc = recv(daemon->routefd, daemon->packet, daemon->packet_buff_sz, 0);
|
||||
|
||||
if (ioctl(fd, SIOCGIFCONF, &ifc) == -1)
|
||||
if (rc < 4)
|
||||
return;
|
||||
|
||||
msg = (struct if_msghdr *)daemon->packet;
|
||||
|
||||
if (rc < msg->ifm_msglen)
|
||||
return;
|
||||
|
||||
if (msg->ifm_version != RTM_VERSION)
|
||||
{
|
||||
static int warned = 0;
|
||||
if (!warned)
|
||||
{
|
||||
if (errno != EINVAL || lastlen != 0)
|
||||
goto err;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ifc.ifc_len == lastlen)
|
||||
break; /* got a big enough buffer now */
|
||||
lastlen = ifc.ifc_len;
|
||||
my_syslog(LOG_WARNING, _("Unknown protocol version from route socket"));
|
||||
warned = 1;
|
||||
}
|
||||
}
|
||||
|
||||
for (ptr = ifc.ifc_buf; ptr < ifc.ifc_buf + ifc.ifc_len; ptr += len )
|
||||
{
|
||||
/* subsequent entries may not be aligned, so copy into
|
||||
an aligned buffer to avoid nasty complaints about
|
||||
unaligned accesses. */
|
||||
#ifdef HAVE_SOCKADDR_SA_LEN
|
||||
len = ((struct ifreq *)ptr)->ifr_addr.sa_len + IF_NAMESIZE;
|
||||
#else
|
||||
len = sizeof(struct ifreq);
|
||||
#endif
|
||||
if (!expand_buf(&ifreq, len))
|
||||
goto err;
|
||||
|
||||
ifr = ifreq.iov_base;
|
||||
memcpy(ifr, ptr, len);
|
||||
|
||||
if (ifr->ifr_addr.sa_family == AF_INET && ipv4_callback)
|
||||
{
|
||||
struct in_addr addr, netmask, broadcast;
|
||||
broadcast.s_addr = 0;
|
||||
addr = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr;
|
||||
if (ioctl(fd, SIOCGIFNETMASK, ifr) == -1)
|
||||
continue;
|
||||
netmask = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr;
|
||||
if (ioctl(fd, SIOCGIFBRDADDR, ifr) != -1)
|
||||
broadcast = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr;
|
||||
if (!((*ipv4_callback)(daemon, addr,
|
||||
(int)if_nametoindex(ifr->ifr_name),
|
||||
netmask, broadcast,
|
||||
parm)))
|
||||
goto err;
|
||||
}
|
||||
#ifdef HAVE_IPV6
|
||||
else if (ifr->ifr_addr.sa_family == AF_INET6 && ipv6_callback)
|
||||
{
|
||||
struct in6_addr *addr = &((struct sockaddr_in6 *)&ifr->ifr_addr)->sin6_addr;
|
||||
/* voodoo to clear interface field in address */
|
||||
if (!(daemon->options & OPT_NOWILD) && IN6_IS_ADDR_LINKLOCAL(addr))
|
||||
{
|
||||
addr->s6_addr[2] = 0;
|
||||
addr->s6_addr[3] = 0;
|
||||
}
|
||||
if (!((*ipv6_callback)(daemon, addr,
|
||||
(int)((struct sockaddr_in6 *)&ifr->ifr_addr)->sin6_scope_id,
|
||||
(int)if_nametoindex(ifr->ifr_name),
|
||||
parm)))
|
||||
goto err;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
errsav = errno;
|
||||
close(fd);
|
||||
errno = errsav;
|
||||
|
||||
return ret;
|
||||
else if (msg->ifm_type == RTM_NEWADDR)
|
||||
{
|
||||
del_family = 0;
|
||||
queue_event(EVENT_NEWADDR);
|
||||
}
|
||||
else if (msg->ifm_type == RTM_DELADDR)
|
||||
{
|
||||
/* There's a race in the kernel, such that if we run iface_enumerate() immediately
|
||||
we get a DELADDR event, the deleted address still appears. Here we store the deleted address
|
||||
in a static variable, and omit it from the set returned by iface_enumerate() */
|
||||
int mask = ((struct ifa_msghdr *)msg)->ifam_addrs;
|
||||
int maskvec[] = { RTA_DST, RTA_GATEWAY, RTA_NETMASK, RTA_GENMASK,
|
||||
RTA_IFP, RTA_IFA, RTA_AUTHOR, RTA_BRD };
|
||||
int of;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0, of = sizeof(struct ifa_msghdr); of < rc && i < sizeof(maskvec)/sizeof(maskvec[0]); i++)
|
||||
if (mask & maskvec[i])
|
||||
{
|
||||
struct sockaddr *sa = (struct sockaddr *)((char *)msg + of);
|
||||
size_t diff = (sa->sa_len != 0) ? sa->sa_len : sizeof(long);
|
||||
|
||||
if (maskvec[i] == RTA_IFA)
|
||||
{
|
||||
del_family = sa->sa_family;
|
||||
if (del_family == AF_INET)
|
||||
del_addr.addr4 = ((struct sockaddr_in *)sa)->sin_addr;
|
||||
else if (del_family == AF_INET6)
|
||||
del_addr.addr6 = ((struct sockaddr_in6 *)sa)->sin6_addr;
|
||||
else
|
||||
del_family = 0;
|
||||
}
|
||||
|
||||
of += diff;
|
||||
/* round up as needed */
|
||||
if (diff & (sizeof(long) - 1))
|
||||
of += sizeof(long) - (diff & (sizeof(long) - 1));
|
||||
}
|
||||
|
||||
queue_event(EVENT_NEWADDR);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* HAVE_BSD_NETWORK */
|
||||
|
||||
2448
src/cache.c
2448
src/cache.c
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user