Compare commits
623 Commits
v2.69test7
...
v2.80test3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 |
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
||||
VERSION export-subst
|
||||
12
.gitignore
vendored
12
.gitignore
vendored
@@ -3,12 +3,12 @@ src/*.mo
|
||||
src/dnsmasq.pot
|
||||
src/dnsmasq
|
||||
src/dnsmasq_baseline
|
||||
src/.configured
|
||||
contrib/wrt/dhcp_lease_time
|
||||
contrib/wrt/dhcp_release
|
||||
debian/base/
|
||||
debian/daemon/
|
||||
src/.copts_*
|
||||
contrib/lease-tools/dhcp_lease_time
|
||||
contrib/lease-tools/dhcp_release
|
||||
contrib/lease-tools/dhcp_release6
|
||||
debian/files
|
||||
debian/substvars
|
||||
debian/utils-substvars
|
||||
debian/utils/
|
||||
debian/trees/
|
||||
debian/build/
|
||||
|
||||
@@ -56,7 +56,7 @@ release 0.95 Major rewrite: remove calls to gethostbyname() and talk
|
||||
any more memory after start-up. The NAT-like forwarding was
|
||||
inspired by a suggestion from Eli Chen <eli@routefree.com>
|
||||
|
||||
release 0.96 Fixed embarrasing thinko in cache linked-list code.
|
||||
release 0.96 Fixed embarrassing thinko in cache linked-list code.
|
||||
|
||||
release 0.98 Some enhancements and bug-fixes.
|
||||
Thanks to "Denis Carre" <denis.carre@laposte.net> and Martin
|
||||
@@ -78,7 +78,7 @@ release 0.98 Some enhancements and bug-fixes.
|
||||
ids, to thwart DNS spoofers.
|
||||
(7) Dnsmasq no longer forwards queries when the
|
||||
"recursion desired" bit is not set in the header.
|
||||
(8) Fixed getopt code to work on compliers with unsigned char.
|
||||
(8) Fixed getopt code to work on compilers with unsigned char.
|
||||
|
||||
release 0.991 Added -b flag: when set causes dnsmasq to always answer
|
||||
reverse queries on the RFC 1918 private IP space itself and
|
||||
@@ -88,7 +88,7 @@ release 0.991 Added -b flag: when set causes dnsmasq to always answer
|
||||
Fixed a bug which stopped dnsmasq working on a box with
|
||||
two or more interfaces with the same IP address.
|
||||
|
||||
Fixed cacheing of CNAMEs. Previously, a CNAME which pointed
|
||||
Fixed caching of CNAMEs. Previously, a CNAME which pointed
|
||||
to a name with many A records would not have all the addresses
|
||||
returned when being answered from the cache.
|
||||
|
||||
@@ -191,7 +191,7 @@ release 1.1 Added --user argument to allow user to change to
|
||||
|
||||
release 1.2 Added IPv6 DNS record support. AAAA records are cached
|
||||
and read from /etc/hosts. Reverse-lookups in the
|
||||
ip6.int and ip6.arpa domains are suppored. Dnsmasq can
|
||||
ip6.int and ip6.arpa domains are supported. Dnsmasq can
|
||||
talk to upstream servers via IPv6 if it finds IP6 addresses
|
||||
in /etc/resolv.conf and it offers DNS service automatically
|
||||
if IPv6 support is present in the kernel.
|
||||
@@ -214,7 +214,7 @@ release 1.3 Some versions of the Linux kernel return EINVAL rather
|
||||
starting, rather than after the first query - principle
|
||||
of least surprise applies here.
|
||||
|
||||
release 1.4 Fix a bug with DHPC lease parsing which broke in
|
||||
release 1.4 Fix a bug with DHCP lease parsing which broke in
|
||||
non-UTC timezones. Thanks to Mark Wormgoor for
|
||||
spotting and diagnosing this. Fixed versions in
|
||||
the .spec files this time. Fixed bug in Suse startup
|
||||
@@ -258,7 +258,7 @@ release 1.7 Fix a problem with cache not clearing properly
|
||||
on receipt of SIGHUP. Bug spotted by Sat Deshpande.
|
||||
|
||||
In group-id changing code:
|
||||
1) Drop supplimentary groups.
|
||||
1) Drop supplementary groups.
|
||||
2) Change gid before dropping root (patch from Soewono Effendi.)
|
||||
3) Change group to "dip" if it exists, to allow access
|
||||
to /etc/ppp/resolv.conf (suggestion from Jorg Sommer.)
|
||||
@@ -297,7 +297,7 @@ release 1.9 Fixes to rpm .spec files.
|
||||
required. The difference is not really visible with
|
||||
bloated libcs like glibc, but should dramatically reduce
|
||||
memory requirements when linked against ulibc for use on
|
||||
embeded routers, and that's the point really. Thanks to
|
||||
embedded routers, and that's the point really. Thanks to
|
||||
Matthew Natalier for prompting this.
|
||||
|
||||
Changed debug mode (-d) so that all logging appears on
|
||||
@@ -319,12 +319,12 @@ release 1.9 Fixes to rpm .spec files.
|
||||
uClinux. Thanks to Matthew Natalier for uClinux stuff.
|
||||
|
||||
release 1.10 Log warnings if resolv.conf or dhcp.leases are not
|
||||
accessable for any reason, as suggested by Hinrich Eilts.
|
||||
accessible for any reason, as suggested by Hinrich Eilts.
|
||||
|
||||
Fixed wrong address printing in error message about
|
||||
no interface with address.
|
||||
|
||||
Updated docs and split installation instuctions into setup.html.
|
||||
Updated docs and split installation instructions into setup.html.
|
||||
|
||||
Fix bug in CNAME chasing code: One CNAME pointing
|
||||
to many A records would lose A records after the
|
||||
@@ -346,7 +346,7 @@ release 1.10 Log warnings if resolv.conf or dhcp.leases are not
|
||||
|
||||
Added -S option to directly specify upstream servers and
|
||||
added ability to direct queries for specific domains to
|
||||
specfic servers. Suggested by Jens Vonderheide.
|
||||
specific servers. Suggested by Jens Vonderheide.
|
||||
|
||||
Upgraded random ID generation - patch from Rob Funk.
|
||||
|
||||
@@ -386,13 +386,13 @@ release 1.11 Actually implement the -R flag promised in the 1.10 man page.
|
||||
names in /etc/hosts -suggestion from Phil Harman.
|
||||
|
||||
Always return a zero time-to-live for names derived from
|
||||
DHCP which stops anthing else caching these
|
||||
DHCP which stops anything else caching these
|
||||
names. Previously the TTL was derived from the lease
|
||||
time but that is incorrect since a lease can be given
|
||||
up early: dnsmasq would know this but anything with the
|
||||
name cached with long TTL would not be updated.
|
||||
|
||||
Extended HAVE_IPV6 config flag to allow compliation on
|
||||
Extended HAVE_IPV6 config flag to allow compilation on
|
||||
old systems which don't have modern library routines
|
||||
like inet_ntop(). Thanks to Phil Harman for the patch.
|
||||
|
||||
@@ -471,7 +471,7 @@ release 1.14 Fixed man page description of -b option which confused
|
||||
/etc/resolv.conf.
|
||||
(Thanks to Klaas Teschauer)
|
||||
|
||||
Check that recieved queries have only rfc1035-legal characters
|
||||
Check that received queries have only rfc1035-legal characters
|
||||
in them. This check is mainly to avoid bad strings being
|
||||
sent to syslog.
|
||||
|
||||
@@ -549,7 +549,7 @@ release 1.16 Allow "/" characters in domain names - this fixes
|
||||
|
||||
release 1.17 Fixed crash with DHCP hostnames > 40 characters.
|
||||
|
||||
Fixed name-comparision routines to not depend on Locale,
|
||||
Fixed name-comparison routines to not depend on Locale,
|
||||
in theory this versions since 1.15 could lock up or give
|
||||
wrong results when run with locale != 'C'.
|
||||
|
||||
@@ -574,7 +574,7 @@ release 1.18 Added round-robin DNS for names which have more than one
|
||||
forwarded because -D is in effect, return NXDOMAIN not
|
||||
an empty reply.
|
||||
|
||||
Add code to return the software version in repsonse to the
|
||||
Add code to return the software version in response to the
|
||||
correct magic query in the same way as BIND. Use
|
||||
"dig version.bind chaos txt" to make the query.
|
||||
|
||||
@@ -635,7 +635,7 @@ release 2.0
|
||||
dynamic allocation.
|
||||
|
||||
Allow dhcp-host options for the same host with different
|
||||
IP adresses where the correct one will be selected for
|
||||
IP addresses where the correct one will be selected for
|
||||
the network the host appears on.
|
||||
|
||||
Fix parsing of --dhcp-option to allow more than one
|
||||
@@ -674,7 +674,7 @@ release 2.1
|
||||
|
||||
Fix unaligned access warnings on BSD/Alpha.
|
||||
|
||||
Allow empty DHCP options, like so: dhpc-option=44
|
||||
Allow empty DHCP options, like so: dhcp-option=44
|
||||
|
||||
Allow single-byte DHCP options like so: dhcp-option=20,1
|
||||
|
||||
@@ -745,7 +745,7 @@ release 2.3
|
||||
around a bug in the DHCP client in HP Jetdirect printers.
|
||||
Thanks to Marko Stolle for finding this problem.
|
||||
|
||||
Return DHCP T1 and T2 times, with "fuzz" to desychronise lease
|
||||
Return DHCP T1 and T2 times, with "fuzz" to desynchronise lease
|
||||
renewals, as specified in the RFC.
|
||||
|
||||
Ensure that the END option is always present in DHCP
|
||||
@@ -838,7 +838,7 @@ release 2.4
|
||||
by Chad Skeeters.
|
||||
|
||||
Fixed bug in /etc/ethers parsing code triggered by tab
|
||||
characters. Qudos to Dag Wieers for hepling to nail that
|
||||
characters. Kudos to Dag Wieers for helping to nail that
|
||||
one.
|
||||
|
||||
Added "bind-interfaces" option correctly.
|
||||
@@ -975,7 +975,7 @@ release 2.8
|
||||
configuration. Specifically: (1) options are matched on
|
||||
the netids from dhcp-range, dhcp-host, vendor class and
|
||||
user class(es). Multiple net-ids are allowed and options
|
||||
are searched on them all. (2) matches agains vendor class
|
||||
are searched on them all. (2) matches against vendor class
|
||||
and user class are now on a substring, if the given
|
||||
string is a substring of the vendor/user class, then a
|
||||
match occurs. Thanks again to Richard Musil for prompting
|
||||
@@ -997,7 +997,7 @@ release 2.8
|
||||
|
||||
Add checks against DHCP clients which return zero-length
|
||||
hostnames. This avoids the potential lease-loss problems
|
||||
reffered to above. Also, if a client sends a hostname when
|
||||
referred to above. Also, if a client sends a hostname when
|
||||
it creates a lease but subsequently sends no or a
|
||||
zero-length hostname whilst renewing, continue to use the
|
||||
existing hostname, don't wipe it out.
|
||||
@@ -1010,7 +1010,7 @@ release 2.9
|
||||
but to the address of another interface were ignored
|
||||
unless the loopback interface was explicitly configured.
|
||||
2) on OpenBSD failure to configure one interface now
|
||||
causes a fatal error on startup rather than an huge
|
||||
causes a fatal error on startup rather than a huge
|
||||
stream of log messages. Thanks to Erik Jan Tromp for
|
||||
finding that bug.
|
||||
|
||||
@@ -1019,7 +1019,7 @@ release 2.9
|
||||
broken. The new algorithm is to pick as before for the
|
||||
first try, but if a query is retried, to send to all
|
||||
available servers in parallel. The first one to reply
|
||||
then becomes prefered for the next query. This should
|
||||
then becomes preferred for the next query. This should
|
||||
improve reliability without generating significant extra
|
||||
upstream load.
|
||||
|
||||
@@ -1027,7 +1027,7 @@ release 2.9
|
||||
unqualified domains introduced in version 2.8
|
||||
|
||||
Allow fallback to "bind-interfaces" at runtime: Some
|
||||
verions of *BSD seem to have enough stuff in the header
|
||||
versions of *BSD seem to have enough stuff in the header
|
||||
files to build but no kernel support. Also now log if
|
||||
"bind-interfaces" is forced on.
|
||||
|
||||
@@ -1049,7 +1049,7 @@ release 2.9
|
||||
first name found is now returned for reverse lookups,
|
||||
rather than all of them.
|
||||
|
||||
Add back fatal errors when nonexistant
|
||||
Add back fatal errors when nonexistent
|
||||
interfaces or interface addresses are given but only in
|
||||
"bind-interfaces" mode. Principle of least surprise applies.
|
||||
|
||||
@@ -1193,7 +1193,7 @@ version 2.14
|
||||
|
||||
version 2.15
|
||||
Fixed NXDOMAIN/NODATA confusion for locally known
|
||||
names. We now return a NODATA reponse for names which are
|
||||
names. We now return a NODATA response for names which are
|
||||
locally known. Now a query for (eg AAAA or MX) for a name
|
||||
with an IPv4 address in /etc/hosts which fails upstream
|
||||
will generate a NODATA response. Note that the query
|
||||
@@ -1229,7 +1229,7 @@ version 2.16
|
||||
|
||||
Set NONBLOCK on all listening sockets to workaround non-POSIX
|
||||
compliance in Linux 2.4 and 2.6. This fixes rare hangs which
|
||||
occured when corrupted packets were received. Thanks to
|
||||
occurred when corrupted packets were received. Thanks to
|
||||
Joris van Rantwijk for chasing that down.
|
||||
|
||||
Updated config.h for NetBSD. Thanks to Martin Lambers.
|
||||
@@ -1297,7 +1297,7 @@ version 2.18
|
||||
interfaces with more than one IPv6 address. Thanks to
|
||||
Martin Pels for help with that.
|
||||
|
||||
Fix problems which occured when more than one dhcp-range
|
||||
Fix problems which occurred when more than one dhcp-range
|
||||
was specified in the same subnet: sometimes parameters
|
||||
(lease time, network-id tag) from the wrong one would be
|
||||
used. Thanks to Rory Campbell-Lange for the bug report.
|
||||
@@ -1314,7 +1314,7 @@ version 2.19
|
||||
Thanks to Richard Atterer for the bug report.
|
||||
|
||||
Check for under-length option fields in DHCP packets, a
|
||||
zero length client-id, in particluar, could seriously
|
||||
zero length client-id, in particular, could seriously
|
||||
confuse dnsmasq 'till now. Thanks to Will Murname for help
|
||||
with that.
|
||||
|
||||
@@ -1389,7 +1389,7 @@ version 2.21
|
||||
recursive queries.
|
||||
|
||||
Fix DHCP address allocation problem when netid tags are in
|
||||
use. Thanks to Will Murnane for the bug report and
|
||||
use. Thanks to Will Murname for the bug report and
|
||||
subsequent testing.
|
||||
|
||||
Add an additional data section to the reply for MX and SRV
|
||||
@@ -1505,7 +1505,7 @@ version 2.23
|
||||
from dnsmasq --version. Thanks to Dirk Schenkewitz for
|
||||
the suggestion.
|
||||
|
||||
Fix pathalogical behaviour when a broken client keeps sending
|
||||
Fix pathological behaviour when a broken client keeps sending
|
||||
DHCPDISCOVER messages repeatedly and fast. Because dealing with
|
||||
each of these takes a few seconds, (because of the ping) then a
|
||||
queue of DHCP packets could build up. Now, the results of a ping
|
||||
@@ -1593,7 +1593,7 @@ version 2.24
|
||||
than one dhcp-range is available. Thanks to Sorin Panca
|
||||
for help chasing this down.
|
||||
|
||||
Added more explict error mesages to the hosts file and
|
||||
Added more explicit error messages to the hosts file and
|
||||
ethers file reading code. Markus Kaiserswerth suffered to
|
||||
make this happen.
|
||||
|
||||
@@ -1617,7 +1617,7 @@ version 2.25
|
||||
|
||||
Fixed Suse spec file - thanks to Steven Springl.
|
||||
|
||||
Fixed DHCP bug when two distict subnets are on the same
|
||||
Fixed DHCP bug when two distinct subnets are on the same
|
||||
physical interface. Thanks to Pawel Zawora for finding
|
||||
this and suggesting the fix.
|
||||
|
||||
@@ -1740,7 +1740,7 @@ version 2.28
|
||||
Fixed regression in netlink code under 2.2.x kernels which
|
||||
occurred in 2.27. Erik Jan Tromp is the vintage kernel fan
|
||||
who found this. P.S. It looks like this "netlink bind:
|
||||
permission denied" problem occured in kernels at least as
|
||||
permission denied" problem occurred in kernels at least as
|
||||
late a 2.4.18. Good information from Alain Richoux.
|
||||
|
||||
Added a warning when it's impossible to give a host its
|
||||
@@ -1761,7 +1761,7 @@ version 2.28
|
||||
Eric House and Eric Spakman for help in chasing this down.
|
||||
|
||||
Tolerate configuration screwups which lead to the DHCP
|
||||
server attemping to allocate its own address to a
|
||||
server attempting to allocate its own address to a
|
||||
client; eg setting the whole subnet range as a DHCP
|
||||
range. Addresses in use by the server are now excluded
|
||||
from use by clients.
|
||||
@@ -2067,7 +2067,7 @@ version 2.36
|
||||
kernel. Thanks to Philip Wall for the bug report.
|
||||
|
||||
Added --dhcp-bridge option, but only to the FreeBSD
|
||||
build. This fixes an oddity with a a particular bridged
|
||||
build. This fixes an oddity with a particular bridged
|
||||
network configuration on FreeBSD. Thanks to Luigi Rizzo
|
||||
for the patch.
|
||||
|
||||
@@ -2273,7 +2273,7 @@ version 2.40
|
||||
this.
|
||||
|
||||
Use client-id as hash-seed for DHCP address allocation
|
||||
with Firewire and Infiniband, as these don't supply an MAC
|
||||
with Firewire and InfiniBand, as these don't supply a MAC
|
||||
address.
|
||||
|
||||
Tweaked TFTP file-open code to make it behave sensibly
|
||||
@@ -2307,7 +2307,7 @@ version 2.40
|
||||
Continue to use unqualified hostnames provided by DHCP
|
||||
clients, even if the domain part is illegal. (The domain
|
||||
is ignored, and an error logged.) Previously in this
|
||||
situation, the whole name whould have been
|
||||
situation, the whole name would have been
|
||||
rejected. Thanks to Jima for the patch.
|
||||
|
||||
Handle EINTR returns from wait() correctly and reap
|
||||
@@ -2319,7 +2319,7 @@ version 2.40
|
||||
leases file and passed to the lease-change
|
||||
script. Suggestion from Ben Voigt.
|
||||
|
||||
Re-run the lease chamge script with an "old" event for
|
||||
Re-run the lease change script with an "old" event for
|
||||
each lease when dnsmasq receives a SIGHUP.
|
||||
|
||||
Added more useful exit codes, including passing on a
|
||||
@@ -2417,7 +2417,7 @@ version 2.41
|
||||
Changed behavior of DHCP server to always return total length of
|
||||
a new lease in DHCPOFFER, even if an existing lease
|
||||
exists. (It used to return the time remaining on the lease
|
||||
whne one existed.) This fixes problems with the Sony Ericsson
|
||||
when one existed.) This fixes problems with the Sony Ericsson
|
||||
K610i phone. Thanks to Hakon Stordahl for finding and
|
||||
fixing this.
|
||||
|
||||
@@ -2433,7 +2433,7 @@ version 2.41
|
||||
|
||||
Add --dhcp-match flag, to check for arbitrary options in
|
||||
DHCP messages from clients. This enables use of dnsmasq
|
||||
with gPXE. Thanks to Rance Hall for the suggestion.
|
||||
with iPXE. Thanks to Rance Hall for the suggestion.
|
||||
|
||||
Added --dhcp-broadcast, to force broadcast replies to DHCP
|
||||
clients which need them but are too dumb or too old to
|
||||
@@ -2476,7 +2476,7 @@ version 2.42
|
||||
|
||||
Fix OS detection logic to cope with GNU/FreeBSD.
|
||||
|
||||
Fix unitialised variable in DBus code - thanks to Roy
|
||||
Fix uninitialised variable in DBus code - thanks to Roy
|
||||
Marples.
|
||||
|
||||
Fix network enumeration code to work on later NetBSD -
|
||||
|
||||
92
FAQ
92
FAQ
@@ -9,7 +9,7 @@ A: The high ports that dnsmasq opens are 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
|
||||
@@ -59,7 +59,7 @@ A: Yes, there is explicit support for *BSD and MacOS X and Solaris.
|
||||
|
||||
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
|
||||
@@ -144,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
|
||||
@@ -180,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
|
||||
@@ -205,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
|
||||
@@ -240,7 +240,7 @@ Q: What are these strange "bind-interface" and "bind-dynamic" options?
|
||||
|
||||
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 bizzare contraints and select the
|
||||
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
|
||||
@@ -252,10 +252,10 @@ A: Dnsmasq from v2.63 can operate in one of three different "networking
|
||||
The three modes are "wildcard", "bind-interfaces" and "bind-dynamic".
|
||||
|
||||
In "wildcard" mode, dnsmasq binds the wildcard IP address (0.0.0.0 or
|
||||
::). This allows it to recieve all the packets sent to the server on
|
||||
::). 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 recieved and
|
||||
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.
|
||||
@@ -276,7 +276,7 @@ A: Dnsmasq from v2.63 can operate in one of three different "networking
|
||||
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 inferfaces. We will deal with these in order.
|
||||
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
|
||||
@@ -297,7 +297,7 @@ A: Dnsmasq from v2.63 can operate in one of three different "networking
|
||||
by dnsmasq when in --bind-interfaces mode. In wildcard or bind-dynamic
|
||||
mode, such interfaces are handled normally.
|
||||
|
||||
A --interface specification for a non-existent interface is a fatal
|
||||
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.
|
||||
|
||||
@@ -313,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/files/auth.html - 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?
|
||||
@@ -349,18 +359,64 @@ A: By default, the identity of a machine is determined by using the
|
||||
method for setting the client-id varies with DHCP client software,
|
||||
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 sumarily abandon a
|
||||
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
|
||||
@@ -488,7 +544,7 @@ 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
|
||||
symtoms have beeen variously reported as continual DHCPINFORM
|
||||
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
|
||||
|
||||
44
Makefile
44
Makefile
@@ -1,4 +1,4 @@
|
||||
# dnsmasq is Copyright (c) 2000-2014 Simon Kelley
|
||||
# dnsmasq is Copyright (c) 2000-2016 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
|
||||
@@ -55,21 +55,28 @@ dbus_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_DBUS $(PKG_CONFIG)
|
||||
dbus_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_DBUS $(PKG_CONFIG) --libs dbus-1`
|
||||
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 lua5.1`
|
||||
lua_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_LUASCRIPT $(PKG_CONFIG) --libs lua5.1`
|
||||
lua_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_LUASCRIPT $(PKG_CONFIG) --cflags lua5.2`
|
||||
lua_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_LUASCRIPT $(PKG_CONFIG) --libs lua5.2`
|
||||
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 $(PKG_CONFIG) --copy -lgmp`
|
||||
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`
|
||||
version = -DVERSION='\"`$(top)/bld/get-version $(top)`\"'
|
||||
|
||||
sum?=$(shell $(CC) -DDNSMASQ_COMPILE_OPTS $(COPTS) -E $(top)/$(SRC)/dnsmasq.h | ( md5sum 2>/dev/null || md5 ) | cut -f 1 -d ' ')
|
||||
sum!=$(CC) -DDNSMASQ_COMPILE_OPTS $(COPTS) -E $(top)/$(SRC)/dnsmasq.h | ( md5sum 2>/dev/null || md5 ) | cut -f 1 -d ' '
|
||||
copts_conf = .copts_$(sum)
|
||||
|
||||
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 \
|
||||
domain.o dnssec.o blockdata.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
|
||||
|
||||
hdrs = dnsmasq.h config.h dhcp-protocol.h dhcp6-protocol.h \
|
||||
dns-protocol.h radv-protocol.h ip6addr.h
|
||||
@@ -77,13 +84,13 @@ hdrs = dnsmasq.h config.h dhcp-protocol.h dhcp6-protocol.h \
|
||||
all : $(BUILDDIR)
|
||||
@cd $(BUILDDIR) && $(MAKE) \
|
||||
top="$(top)" \
|
||||
build_cflags="$(version) $(dbus_cflags) $(idn_cflags) $(ct_cflags) $(lua_cflags) $(nettle_cflags)" \
|
||||
build_libs="$(dbus_libs) $(idn_libs) $(ct_libs) $(lua_libs) $(sunos_libs) $(nettle_libs) $(gmp_libs)" \
|
||||
build_cflags="$(version) $(dbus_cflags) $(idn2_cflags) $(idn_cflags) $(ct_cflags) $(lua_cflags) $(nettle_cflags)" \
|
||||
build_libs="$(dbus_libs) $(idn2_libs) $(idn_libs) $(ct_libs) $(lua_libs) $(sunos_libs) $(nettle_libs) $(gmp_libs)" \
|
||||
-f $(top)/Makefile dnsmasq
|
||||
|
||||
mostly_clean :
|
||||
rm -f $(BUILDDIR)/*.mo $(BUILDDIR)/*.pot
|
||||
rm -f $(BUILDDIR)/.configured $(BUILDDIR)/*.o $(BUILDDIR)/dnsmasq.a $(BUILDDIR)/dnsmasq
|
||||
rm -f $(BUILDDIR)/.copts_* $(BUILDDIR)/*.o $(BUILDDIR)/dnsmasq.a $(BUILDDIR)/dnsmasq
|
||||
|
||||
clean : mostly_clean
|
||||
rm -f $(BUILDDIR)/dnsmasq_baseline
|
||||
@@ -93,7 +100,8 @@ clean : mostly_clean
|
||||
install : all install-common
|
||||
|
||||
install-common :
|
||||
$(INSTALL) -d $(DESTDIR)$(BINDIR) -d $(DESTDIR)$(MANDIR)/man8
|
||||
$(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)
|
||||
|
||||
@@ -101,8 +109,8 @@ all-i18n : $(BUILDDIR)
|
||||
@cd $(BUILDDIR) && $(MAKE) \
|
||||
top="$(top)" \
|
||||
i18n=-DLOCALEDIR=\'\"$(LOCALEDIR)\"\' \
|
||||
build_cflags="$(version) $(dbus_cflags) $(ct_cflags) $(lua_cflags) $(nettle_cflags) `$(PKG_CONFIG) --cflags libidn`" \
|
||||
build_libs="$(dbus_libs) $(ct_libs) $(lua_libs) $(sunos_libs) $(nettle_libs) $(gmp_libs) `$(PKG_CONFIG) --libs libidn`" \
|
||||
build_cflags="$(version) $(dbus_cflags) $(idn2_cflags) $(idn_cflags) $(ct_cflags) $(lua_cflags) $(nettle_cflags)" \
|
||||
build_libs="$(dbus_libs) $(idn2_libs) $(idn_libs) $(ct_libs) $(lua_libs) $(sunos_libs) $(nettle_libs) $(gmp_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; \
|
||||
@@ -113,12 +121,12 @@ install-i18n : all-i18n install-common
|
||||
cd $(MAN); ../bld/install-man $(DESTDIR)$(MANDIR) $(INSTALL)
|
||||
|
||||
merge :
|
||||
@cd $(BUILDDIR) && $(MAKE) -f $(top)/Makefile dnsmasq.pot
|
||||
@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
|
||||
|
||||
# Cannonicalise .po file.
|
||||
# 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;
|
||||
@@ -137,19 +145,21 @@ bloatcheck : $(BUILDDIR)/dnsmasq_baseline mostly_clean all
|
||||
$(top)/bld/bloat-o-meter dnsmasq_baseline dnsmasq; \
|
||||
size dnsmasq_baseline dnsmasq
|
||||
|
||||
# rules below are targets in recusive makes with cwd=$(BUILDDIR)
|
||||
# rules below are targets in recursive makes with cwd=$(BUILDDIR)
|
||||
|
||||
.configured: $(hdrs)
|
||||
@rm -f *.o
|
||||
$(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 : .configured $(hdrs) $(objs)
|
||||
dnsmasq : $(objs)
|
||||
$(CC) $(LDFLAGS) -o $@ $(objs) $(build_libs) $(LIBS)
|
||||
|
||||
dnsmasq.pot : $(objs:.o=.c) $(hdrs)
|
||||
|
||||
@@ -9,7 +9,9 @@ LOCAL_SRC_FILES := bpf.c cache.c dbus.c dhcp.c dnsmasq.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
|
||||
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
|
||||
|
||||
LOCAL_MODULE := dnsmasq
|
||||
|
||||
|
||||
@@ -11,16 +11,24 @@
|
||||
# If there is more than one v[0-9].* tag, sort them and use the
|
||||
# first. This favours, eg v2.63 over 2.63rc6.
|
||||
|
||||
if which git >/dev/null 2>&1 && [ -d $1/.git ]; then
|
||||
cd $1; git describe | sed 's/^v//'
|
||||
# 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.
|
||||
# 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 | head -n 1 | sed 's/^v//'
|
||||
echo "${vers}" | sort -r | head -n 1 | sed 's/^v//'
|
||||
else
|
||||
cat $1/VERSION
|
||||
fi
|
||||
|
||||
@@ -11,11 +11,19 @@ in=`cat`
|
||||
|
||||
if grep "^\#[[:space:]]*define[[:space:]]*$search" config.h >/dev/null 2>&1 || \
|
||||
echo $in | grep $search >/dev/null 2>&1; then
|
||||
|
||||
# Nasty, nasty, in --copy, arg 2 is another config to search for, use with NO_GMP
|
||||
if [ $op = "--copy" ]; then
|
||||
pkg="$*"
|
||||
if grep "^\#[[:space:]]*define[[:space:]]*$pkg" config.h >/dev/null 2>&1 || \
|
||||
echo $in | grep $pkg >/dev/null 2>&1; then
|
||||
pkg=""
|
||||
else
|
||||
pkg="$*"
|
||||
fi
|
||||
elif grep "^\#[[:space:]]*define[[:space:]]*${search}_STATIC" config.h >/dev/null 2>&1 || \
|
||||
echo $in | grep ${search}_STATIC >/dev/null 2>&1; then
|
||||
pkg=`$pkg --static $op $*`
|
||||
else
|
||||
pkg=`$pkg $op $*`
|
||||
pkg=`$pkg $op $*`
|
||||
fi
|
||||
|
||||
if grep "^\#[[:space:]]*define[[:space:]]*${search}_STATIC" config.h >/dev/null 2>&1 || \
|
||||
|
||||
@@ -22,7 +22,7 @@ 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 dnsmaq, reboot or use the command:
|
||||
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:
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
This is a patch against SuSEfirewall2-3.1-206 (SuSE 9.x and older)
|
||||
It fixes the depancy from the dns daemon name 'named'
|
||||
It fixes the dependency 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'
|
||||
The SuSE people think the name of the dns server will always 'named'
|
||||
|
||||
|
||||
--- /sbin/SuSEfirewall2.orig 2004-01-23 13:30:09.000000000 +0100
|
||||
|
||||
@@ -13,10 +13,10 @@ 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
|
||||
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,
|
||||
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
|
||||
|
||||
@@ -40,7 +40,7 @@ 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
|
||||
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.
|
||||
|
||||
@@ -55,7 +55,7 @@ Index: src/dnsmasq.c
|
||||
}
|
||||
|
||||
@@ -434,7 +433,7 @@
|
||||
/* lose the setuid and setgid capbilities */
|
||||
/* lose the setuid and setgid capabilities */
|
||||
if (capset(hdr, data) == -1)
|
||||
{
|
||||
- send_event(err_pipe[1], EVENT_CAP_ERR, errno);
|
||||
|
||||
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
|
||||
@@ -168,7 +168,7 @@ int main(int argc, char **argv)
|
||||
*(p++) = 1;
|
||||
*(p++) = DHCPINFORM;
|
||||
|
||||
/* Explicity request the lease time, it won't be sent otherwise:
|
||||
/* Explicitly request the lease time, it won't be sent otherwise:
|
||||
this is a dnsmasq extension, not standard. */
|
||||
*(p++) = OPTION_REQUESTED_OPTIONS;
|
||||
*(p++) = 1;
|
||||
@@ -206,13 +206,13 @@ int main(int argc, char **argv)
|
||||
{
|
||||
unsigned int x;
|
||||
if ((x = t/86400))
|
||||
printf("%dd", x);
|
||||
printf("%ud", x);
|
||||
if ((x = (t/3600)%24))
|
||||
printf("%dh", x);
|
||||
printf("%uh", x);
|
||||
if ((x = (t/60)%60))
|
||||
printf("%dm", x);
|
||||
printf("%um", x);
|
||||
if ((x = t%60))
|
||||
printf("%ds", x);
|
||||
printf("%us", x);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -117,7 +117,7 @@ static ssize_t netlink_recv(int fd)
|
||||
msg.msg_flags = 0;
|
||||
while ((rc = recvmsg(fd, &msg, MSG_PEEK)) == -1 && errno == EINTR);
|
||||
|
||||
/* 2.2.x doesn't suport MSG_PEEK at all, returning EOPNOTSUPP, so we just grab a
|
||||
/* 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)
|
||||
{
|
||||
@@ -277,6 +277,11 @@ int main(int argc, char **argv)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (inet_addr(argv[2]) == INADDR_NONE)
|
||||
{
|
||||
perror("invalid ip address");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
lease.s_addr = inet_addr(argv[2]);
|
||||
server = find_interface(lease, nl, if_nametoindex(argv[1]));
|
||||
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>.
|
||||
|
||||
|
||||
496
contrib/lease-tools/dhcp_release6.c
Normal file
496
contrib/lease-tools/dhcp_release6.c
Normal file
@@ -0,0 +1,496 @@
|
||||
/*
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
inet_pton(AF_INET6, "::", &client_addr.sin6_addr);
|
||||
bind(sock, (struct sockaddr*)&client_addr, sizeof(struct sockaddr_in6));
|
||||
inet_pton(AF_INET6, DHCP6_MULTICAST_ADDRESS, &server_addr.sin6_addr);
|
||||
server_addr.sin6_port = htons(DHCP6_SERVER_PORT);
|
||||
int16_t recv_size = 0;
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
if (sendto(sock, packet->buf, packet->len, 0, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
|
||||
{
|
||||
perror("sendto failed");
|
||||
exit(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");
|
||||
}
|
||||
}
|
||||
|
||||
int16_t result = parse_packet(response, recv_size);
|
||||
if (result == NOT_REPLY_CODE)
|
||||
{
|
||||
sleep(1);
|
||||
continue;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
STATUS_FILE="/tmp/dnsmasq-ip-mac.status"
|
||||
|
||||
# Script for dnsmasq lease-change hook.
|
||||
# Maintains the above file with a IP address/MAC address pairs,
|
||||
# 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.
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# 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 seperated with a
|
||||
# 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".
|
||||
|
||||
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 ash 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/ash
|
||||
# $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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[Unit]
|
||||
Description=A lightweight DHCP and caching DNS server
|
||||
Description=dnsmasq - A lightweight DHCP and caching DNS server
|
||||
|
||||
[Service]
|
||||
Type=dbus
|
||||
|
||||
@@ -2,7 +2,7 @@ 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 acceptible
|
||||
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
|
||||
|
||||
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
|
||||
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;
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
This is the README for the DNSmasq webmin module.
|
||||
This is the README for the Dnsmasq webmin module.
|
||||
|
||||
Problems:
|
||||
|
||||
@@ -48,7 +48,7 @@ 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 usefull)
|
||||
(rather the opposite - I'd be pleased someone found it useful)
|
||||
|
||||
Cheers,
|
||||
Neil Fisher <neil@magnecor.com.au>
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
CFLAGS?= -O2 -Wall -W
|
||||
|
||||
all: dhcp_release dhcp_lease_time
|
||||
|
||||
clean:
|
||||
rm -f *~ *.o core dhcp_release dhcp_lease_time
|
||||
@@ -4,7 +4,7 @@ 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 fileystems read-only after boot,
|
||||
*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:
|
||||
|
||||
@@ -62,7 +62,7 @@ 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
|
||||
ammended, probably by changing it to read the output of
|
||||
amended, probably by changing it to read the output of
|
||||
`lease_update init` instead.
|
||||
|
||||
|
||||
|
||||
@@ -40,6 +40,14 @@ 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.
|
||||
|
||||
SetBogusPrivOption
|
||||
------------------
|
||||
Takes boolean, sets or resets the --bogus-priv option.
|
||||
|
||||
SetServers
|
||||
----------
|
||||
Returns nothing. Takes a set of arguments representing the new
|
||||
@@ -152,6 +160,89 @@ for SetServersEx is represented as
|
||||
"/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.
|
||||
|
||||
|
||||
|
||||
2. SIGNALS
|
||||
|
||||
230
debian/changelog
vendored
230
debian/changelog
vendored
@@ -1,6 +1,218 @@
|
||||
dnsmasq (2.79-1) unstable; urgency=low
|
||||
|
||||
* New upstream. (closes: #888200)
|
||||
* Fix trust-anchor regex in init script. (closes: #884347)
|
||||
* Fix exit code for dhcp_release6 (closes: #883596)
|
||||
* Add project homepage to control file. (closes: #887764)
|
||||
* New binary package dnsmasq-base-lua, includes Lua support.
|
||||
* Remove hardwired shlibs dependency for libnettle 3.3 and
|
||||
fix code to avoid ABI breakage as long as compiled against
|
||||
libnettle 3.4 or later. (closes: #891315)
|
||||
|
||||
-- Simon Kelley <simon@thekelleys.org.uk> Fri, 16 Feb 2018 19:54:22 +0000
|
||||
|
||||
dnsmasq (2.78-3) unstable; urgency=high
|
||||
|
||||
* Make failure of pidfile chown a warning. (closes: #889857)
|
||||
|
||||
-- Simon Kelley <simon@thekelleys.org.uk> Thu, 8 Feb 2018 21:26:30 +0000
|
||||
|
||||
dnsmasq (2.78-2) unstable; urgency=high
|
||||
|
||||
* Change ownership of pid file, to keep systemd happy. (closes: #889336)
|
||||
|
||||
-- Simon Kelley <simon@thekelleys.org.uk> Tue, 6 Feb 2018 17:21:30 +0000
|
||||
|
||||
dnsmasq (2.78-1) unstable; urgency=high
|
||||
|
||||
* New upstream.
|
||||
Security fixes for CVE-2017-13704 (closes: #877102)
|
||||
Security fixes for CVE-2017-14491 - CVE-2017-14496 inclusive.
|
||||
|
||||
-- Simon Kelley <simon@thekelleys.org.uk> Sun, 29 Sep 2017 21:34:00 +0000
|
||||
|
||||
dnsmasq (2.77-2) unstable; urgency=low
|
||||
|
||||
* Improve sed regexp for parsing root.ds.
|
||||
|
||||
-- Simon Kelley <simon@thekelleys.org.uk> Mon, 5 Jun 2017 20:46:32 +0000
|
||||
|
||||
dnsmasq (2.77-1) unstable; urgency=low
|
||||
|
||||
* New upstream.
|
||||
* Don't register as a resolvconf source when config file
|
||||
includes port=0 to disable DNS.
|
||||
* Handle gratuitous format change in /usr/share/dns/root.ds
|
||||
(closes: #858506) (closes: #860064)
|
||||
* Add lsb-base dependency.
|
||||
|
||||
-- Simon Kelley <simon@thekelleys.org.uk> Tue, 11 Apr 2017 14:19:20 +0000
|
||||
|
||||
dnsmasq (2.76-5) unstable; urgency=medium
|
||||
|
||||
* Nail libnettle dependency to avoid ABI incompatibility.
|
||||
(closes: #846642)
|
||||
|
||||
-- Simon Kelley <simon@thekelleys.org.uk> Wed, 14 Dec 2016 17:58:10 +0000
|
||||
|
||||
dnsmasq (2.76-4.1) unstable; urgency=medium
|
||||
|
||||
* Non-maintainer upload.
|
||||
* Add two upstream patches to fix binding to an interface being
|
||||
destroyed and recreated. Closes: #834722.
|
||||
+ 2675f2061525bc954be14988d64384b74aa7bf8b
|
||||
+ 16800ea072dd0cdf14d951c4bb8d2808b3dfe53d
|
||||
|
||||
-- Vincent Bernat <bernat@debian.org> Sat, 26 Nov 2016 20:15:34 +0100
|
||||
|
||||
dnsmasq (2.76-4) unstable; urgency=medium
|
||||
|
||||
* Non-maintainer upload.
|
||||
* Fix FTCBFS: Use triplet-prefixed tools. (closes: #836072)
|
||||
|
||||
-- Helmut Grohne <helmut@subdivi.de> Tue, 30 Aug 2016 13:59:12 +0200
|
||||
|
||||
dnsmasq (2.76-3) unstable; urgency=medium
|
||||
|
||||
* Bump auth zone serial on SIGHUP. (closes: #833733)
|
||||
|
||||
-- Simon Kelley <simon@thekelleys.org.uk> Sat, 13 Aug 2016 21:43:10 +0000
|
||||
|
||||
dnsmasq (2.76-2) unstable; urgency=medium
|
||||
|
||||
* Fix to systemd to fix failure to start with bridge interface.
|
||||
(Closes: #831372)
|
||||
|
||||
-- Simon Kelley <simon@thekelleys.org.uk> Sat, 16 Jul 2016 22:09:10 +0000
|
||||
|
||||
dnsmasq (2.76-1.2) unstable; urgency=medium
|
||||
|
||||
* Non-maintainer upload.
|
||||
* dnsmasq: Install marker file to determine package installed state,
|
||||
for the benefit of the init script. (Closes: #819856)
|
||||
|
||||
-- Christian Hofstaedtler <zeha@debian.org> Sat, 16 Jul 2016 00:17:57 +0000
|
||||
|
||||
dnsmasq (2.76-1.1) unstable; urgency=medium
|
||||
|
||||
* Non-maintainer upload.
|
||||
* Provide nss-lookup.target for systemd, without relying on insserv.
|
||||
Patch from Michael Biebl <biebl@debian.org>. (Closes: #826242)
|
||||
|
||||
-- Christian Hofstaedtler <zeha@debian.org> Fri, 01 Jul 2016 13:41:11 +0000
|
||||
|
||||
dnsmasq (2.76-1) unstable; urgency=low
|
||||
|
||||
* New upstream. (closes: #798586)
|
||||
* Use /run/dnsmasq directly, rather than relying on link from /var/run
|
||||
to avoid problems before /var is mounted. (closes: #800351)
|
||||
* Test for the existence of /usr/share/doc/dnsmasq rather then
|
||||
/etc/dnsmasq.d/README in the daemon startup script. (closes: #819856)
|
||||
* Add --help to manpage and mention dhcp6 in summary. (closes: #821226)
|
||||
|
||||
-- Simon Kelley <simon@thekelleys.org.uk> Thu, 10 Sep 2015 23:07:21 +0000
|
||||
|
||||
dnsmasq (2.75-1) unstable; urgency=low
|
||||
|
||||
* New upstream. (closes: #794095)
|
||||
|
||||
-- Simon Kelley <simon@thekelleys.org.uk> Thu, 30 Jul 2015 20:58:31 +0000
|
||||
|
||||
dnsmasq (2.74-1) unstable; urgency=low
|
||||
|
||||
* New upstream. (LP: #1468611)
|
||||
|
||||
-- Simon Kelley <simon@thekelleys.org.uk> Wed, 15 Jul 2015 21:54:11 +0000
|
||||
|
||||
dnsmasq (2.73-2) unstable; urgency=low
|
||||
|
||||
* Fix behaviour of empty --conf-file (closes: #790341)
|
||||
|
||||
-- Simon Kelley <simon@thekelleys.org.uk> Thu, 7 Jul 2015 21:46:42 +0000
|
||||
|
||||
dnsmasq (2.73-1) unstable; urgency=low
|
||||
|
||||
* New upstream. (closes: #786996)
|
||||
* Tweak field width in cache dump to avoid truncating IPv6
|
||||
addresses. (closes: #771557)
|
||||
* Add newline at the end of example config file. (LP: #1416895)
|
||||
* Make Debian package build reproducible. (closes: #777323)
|
||||
* Add Requires=network.target to systemd unit.
|
||||
|
||||
-- Simon Kelley <simon@thekelleys.org.uk> Thu, 4 Jun 2015 22:31:42 +0000
|
||||
|
||||
dnsmasq (2.72-3) unstable; urgency=medium
|
||||
|
||||
* debian/systemd.service: switch from Type=dbus to Type=forking.
|
||||
dnsmasq does not depend on dbus, but Type=dbus systemd services cannot
|
||||
work without it. (Closes: #769486, #776530)
|
||||
- debian/init: when called with systemd-exec argument, let dnsmasq
|
||||
go into the background, so Type=forking can detect when it is ready
|
||||
* Remove line containing only whitespace in debian/control.
|
||||
(closes: #777571)
|
||||
|
||||
-- Simon Kelley <simon@thekelleys.org.uk> Wed, 11 Feb 2015 21:56:12 +0000
|
||||
|
||||
dnsmasq (2.72-2) unstable; urgency=low
|
||||
|
||||
* Fix build in Debian-kFreeBSD. (closes: #763693)
|
||||
|
||||
-- Simon Kelley <simon@thekelleys.org.uk> Thu, 02 Oct 2014 22:34:12 +0000
|
||||
|
||||
dnsmasq (2.72-1) unstable; urgency=low
|
||||
|
||||
* New upstream.
|
||||
* If dns-root-data package is installed, use it to set the DNSSEC
|
||||
trust anchor(s). Recommend dns-root-data. (closes: #760460)
|
||||
* Handle AD bit correctly in replies from cache. (closes: #761654)
|
||||
|
||||
-- Simon Kelley <simon@thekelleys.org.uk> Tue, 20 May 2014 21:01:11 +0000
|
||||
|
||||
dnsmasq (2.71-1) unstable; urgency=low
|
||||
|
||||
* New upstream.
|
||||
* Fix 100% CPU-usage bug when dnsmasq started with cachesize
|
||||
set to zero. (LP: #1314697)
|
||||
|
||||
-- Simon Kelley <simon@thekelleys.org.uk> Fri, 16 May 2014 20:17:10 +0000
|
||||
|
||||
dnsmasq (2.70-3) unstable; urgency=medium
|
||||
|
||||
* Write a pid-file, even when being started using systemd, since
|
||||
other components may wish to signal dnsmasq.
|
||||
* Enable dnsmasq systemd unit on install. Otherwise dnsmasq does not run on
|
||||
fresh installations (without administrator handholding) and even worse it
|
||||
is disabled on systems switching from sysv to systemd. Modify
|
||||
postinst/postrm exactly as dh_systemd would, add dependency on
|
||||
init-system-helpers. Closes: #724602
|
||||
|
||||
-- Simon Kelley <simon@thekelleys.org.uk> Sun, 11 May 2014 17:45:21 +0000
|
||||
|
||||
dnsmasq (2.70-2) unstable; urgency=low
|
||||
|
||||
* Ensure daemon not stared if dnsmasq package has been removed,
|
||||
even if dnsmasq-base is still installed. (closes: #746941)
|
||||
* Tidy cruft in initscript. (closes: #746940)
|
||||
|
||||
-- Simon Kelley <simon@thekelleys.org.uk> Sun, 04 May 2014 21:34:11 +0000
|
||||
|
||||
dnsmasq (2.70-1) unstable; urgency=low
|
||||
|
||||
* New upstream.
|
||||
|
||||
-- Simon Kelley <simon@thekelleys.org.uk> Wed, 23 Apr 2014 15:14:42 +0000
|
||||
|
||||
dnsmasq (2.69-1) unstable; urgency=low
|
||||
|
||||
* New upstream.
|
||||
* Set --local-service. (closes: #732610)
|
||||
This tells dnsmasq to ignore DNS requests that don't come
|
||||
from a local network. It's automatically ignored if
|
||||
--interface --except-interface, --listen-address or
|
||||
--auth-server exist in the configuration, so for most
|
||||
installations, it will have no effect, but for
|
||||
otherwise-unconfigured installations, it stops dnsmasq
|
||||
from being vulnerable to DNS-reflection attacks.
|
||||
|
||||
-- Simon Kelley <simon@thekelleys.org.uk> Tue, 4 Feb 2014 16:28:12 +0000
|
||||
|
||||
@@ -548,7 +760,7 @@ dnsmasq (2.26-1) unstable; urgency=high
|
||||
dnsmasq (2.25-1) unstable; urgency=low
|
||||
|
||||
* Remove bashisms in postinst and prerm scripts.
|
||||
* Remove misconcieved dependency on locales.
|
||||
* Remove misconceived dependency on locales.
|
||||
* Depend on adduser.
|
||||
|
||||
-- Simon Kelley <simon@thekelleys.org.uk> Thu, 01 Dec 2005 21:02:12 +0000
|
||||
@@ -570,7 +782,7 @@ dnsmasq (2.23-1) unstable; urgency=low
|
||||
* Add support for DNSMASQ_EXCEPT in /etc/defaults/dnsmasq.
|
||||
putting "lo" in this also disables resolvconf support.
|
||||
* No longer delete pre-existing /etc/init.d symlinks. The
|
||||
change in default runlevels which neccesitated this
|
||||
change in default runlevels which necessitated this
|
||||
is now ancient history and anyway the startup script now
|
||||
behaves when called twice. (closes: #312111)
|
||||
* Tightened config-file parser. (closes: #317030)
|
||||
@@ -755,7 +967,7 @@ dnsmasq (2.6-3) unstable; urgency=low
|
||||
|
||||
* Removed reload command from start script and moved force-reload
|
||||
to be equivalent to restart. This is needed to be policy compliant
|
||||
since SIHGUP doesn't cause dnsmasq to reload its configuration file,
|
||||
since SIGHUP doesn't cause dnsmasq to reload its configuration file,
|
||||
only the /etc/hosts, /etc/resolv.conf etc. (closes: #244208)
|
||||
|
||||
-- Simon Kelley <simon@thekelleys.org.uk> Sun, 18 Apr 2004 14:40:51 +0000
|
||||
@@ -845,8 +1057,8 @@ dnsmasq (2.0-1) unstable; urgency=low
|
||||
* New upstream: This removes the ability to read the
|
||||
the leases file of ISC DHCP and replaces it with a built-in
|
||||
DHCP server. Apologies in advance for breaking backwards
|
||||
compatibilty, but this replaces a bit of a hack (the ISC stuff)
|
||||
with a nicely engineered and much more apropriate solution.
|
||||
compatibility, but this replaces a bit of a hack (the ISC stuff)
|
||||
with a nicely engineered and much more appropriate solution.
|
||||
Wearing my upstream-maintainer hat, I want to lose the hack now,
|
||||
rather than have to support it into Sarge.
|
||||
* New upstream closes some bugs since they become
|
||||
@@ -872,7 +1084,7 @@ dnsmasq (1.18-1) unstable; urgency=low
|
||||
* New upstream which does round-robin. (closes: #215460)
|
||||
* Removed conflicts with other dns servers since it is now
|
||||
possible to control exactly where dnsmasq listens on multi-homed
|
||||
hosts, making co-existance with another nameserver
|
||||
hosts, making co-existence with another nameserver
|
||||
a viable proposition. (closes #176163)
|
||||
* New upstream allows _ in hostnames and check for illegal
|
||||
names in /etc/hosts. (closes: #218842)
|
||||
@@ -958,13 +1170,13 @@ dnsmasq (1.11-2) unstable; urgency=low
|
||||
|
||||
dnsmasq (1.11-1) unstable; urgency=low
|
||||
|
||||
* New uptream.
|
||||
* New upstream.
|
||||
|
||||
-- Simon Kelley <simon@thekelleys.org.uk> Tues, 12 Jan 2003 22:25:17 -0100
|
||||
|
||||
dnsmasq (1.10-1) unstable; urgency=low
|
||||
|
||||
* New uptream.
|
||||
* New upstream.
|
||||
* Force service to stop in postinst before restarting. I don't
|
||||
understand the circumstances under which it would still be running at
|
||||
this point, but this is the correct fix anyway. (closes: #169718)
|
||||
@@ -976,7 +1188,7 @@ dnsmasq (1.10-1) unstable; urgency=low
|
||||
|
||||
dnsmasq (1.9-1) unstable; urgency=low
|
||||
|
||||
* New uptream.
|
||||
* New upstream.
|
||||
|
||||
-- Simon Kelley <simon@thekelleys.org.uk> Mon, 23 Sept 2002 21:35:07 -0100
|
||||
|
||||
|
||||
31
debian/control
vendored
31
debian/control
vendored
@@ -2,13 +2,17 @@ Source: dnsmasq
|
||||
Section: net
|
||||
Priority: optional
|
||||
Build-depends: gettext, libnetfilter-conntrack-dev [linux-any],
|
||||
libidn11-dev, libdbus-1-dev (>=0.61), libgmp-dev, nettle-dev (>=2.4-3)
|
||||
libidn11-dev, libdbus-1-dev (>=0.61), libgmp-dev,
|
||||
nettle-dev (>=2.4-3), libbsd-dev [!linux-any],
|
||||
liblua5.2-dev
|
||||
Maintainer: Simon Kelley <simon@thekelleys.org.uk>
|
||||
Standards-Version: 3.9.3
|
||||
Homepage: http://www.thekelleys.org.uk/dnsmasq/doc.html
|
||||
Standards-Version: 3.9.8
|
||||
|
||||
Package: dnsmasq
|
||||
Architecture: all
|
||||
Depends: netbase, dnsmasq-base(>= ${binary:Version})
|
||||
Depends: netbase, dnsmasq-base,
|
||||
init-system-helpers (>= 1.18~), lsb-base (>= 3.0-6)
|
||||
Suggests: resolvconf
|
||||
Conflicts: resolvconf (<<1.15)
|
||||
Description: Small caching DNS proxy and DHCP/TFTP server
|
||||
@@ -25,12 +29,29 @@ Package: dnsmasq-base
|
||||
Architecture: any
|
||||
Depends: adduser, ${shlibs:Depends}
|
||||
Breaks: dnsmasq (<< 2.63-1~)
|
||||
Replaces: dnsmasq (<< 2.63-1~)
|
||||
Replaces: dnsmasq (<< 2.63-1~), dnsmasq-base
|
||||
Recommends: dns-root-data
|
||||
Provides: dnsmasq-base
|
||||
Conflicts: dnsmasq-base-lua
|
||||
Description: Small caching DNS proxy and DHCP/TFTP server
|
||||
This package contains the dnsmasq executable and documentation, but
|
||||
not the infrastructure required to run it as a system daemon. For
|
||||
that, install the dnsmasq package.
|
||||
|
||||
Package: dnsmasq-base-lua
|
||||
Architecture: any
|
||||
Depends: adduser, ${shlibs:Depends}
|
||||
Breaks: dnsmasq (<< 2.63-1~)
|
||||
Replaces: dnsmasq (<< 2.63-1~), dnsmasq-base
|
||||
Recommends: dns-root-data
|
||||
Provides: dnsmasq-base
|
||||
Conflicts: dnsmasq-base
|
||||
Description: Small caching DNS proxy and DHCP/TFTP server
|
||||
This package contains the dnsmasq executable and documentation, but
|
||||
not the infrastructure required to run it as a system daemon. For
|
||||
that, install the dnsmasq package. This package is an alternative
|
||||
to dnsmasq-base which includes the LUA interpreter.
|
||||
|
||||
Package: dnsmasq-utils
|
||||
Architecture: linux-any
|
||||
Depends: ${shlibs:Depends}
|
||||
@@ -39,5 +60,3 @@ Description: Utilities for manipulating DHCP leases
|
||||
Small utilities to query a DHCP server's lease database and
|
||||
remove leases from it. These programs are distributed with dnsmasq
|
||||
and may not work correctly with other DHCP servers.
|
||||
|
||||
|
||||
|
||||
2
debian/copyright
vendored
2
debian/copyright
vendored
@@ -1,4 +1,4 @@
|
||||
dnsmasq is Copyright (c) 2000-2013 Simon Kelley
|
||||
dnsmasq is Copyright (c) 2000-2018 Simon Kelley
|
||||
|
||||
It was downloaded from: http://www.thekelleys.org.uk/dnsmasq/
|
||||
|
||||
|
||||
2
debian/default
vendored
2
debian/default
vendored
@@ -27,7 +27,7 @@ CONFIG_DIR=/etc/dnsmasq.d,.dpkg-dist,.dpkg-old,.dpkg-new
|
||||
# If the resolvconf package is installed, dnsmasq will use its output
|
||||
# rather than the contents of /etc/resolv.conf to find upstream
|
||||
# nameservers. Uncommenting this line inhibits this behaviour.
|
||||
# Not that including a "resolv-file=<filename>" line in
|
||||
# Note that including a "resolv-file=<filename>" line in
|
||||
# /etc/dnsmasq.conf is not enough to override resolvconf if it is
|
||||
# installed: the line below must be uncommented.
|
||||
#IGNORE_RESOLVCONF=yes
|
||||
|
||||
6
debian/dnsmasq-base.postinst
vendored
6
debian/dnsmasq-base.postinst
vendored
@@ -17,8 +17,8 @@ if [ "$1" = "configure" ]; then
|
||||
# dnsmasq-base, but it's much easier to create it here so that
|
||||
# we don't have synchronisation issues with the creation of the
|
||||
# dnsmasq user.
|
||||
if [ ! -d /var/run/dnsmasq ]; then
|
||||
mkdir /var/run/dnsmasq
|
||||
chown dnsmasq:nogroup /var/run/dnsmasq
|
||||
if [ ! -d /run/dnsmasq ]; then
|
||||
mkdir /run/dnsmasq
|
||||
chown dnsmasq:nogroup /run/dnsmasq
|
||||
fi
|
||||
fi
|
||||
|
||||
2
debian/dnsmasq-base.postrm
vendored
2
debian/dnsmasq-base.postrm
vendored
@@ -7,5 +7,5 @@ if [ purge = "$1" ]; then
|
||||
else
|
||||
echo >&2 "not removing dnsmasq system account because deluser command was not found"
|
||||
fi
|
||||
rm -rf /var/run/dnsmasq
|
||||
rm -rf /run/dnsmasq
|
||||
fi
|
||||
|
||||
70
debian/init
vendored
70
debian/init
vendored
@@ -8,7 +8,8 @@
|
||||
# Description: DHCP and DNS server
|
||||
### END INIT INFO
|
||||
|
||||
set +e # Don't exit on error status
|
||||
# Don't exit on error status
|
||||
set +e
|
||||
|
||||
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
|
||||
DAEMON=/usr/sbin/dnsmasq
|
||||
@@ -29,6 +30,11 @@ if [ -r /etc/default/locale ]; then
|
||||
export LANG
|
||||
fi
|
||||
|
||||
# The following test ensures the dnsmasq service is not started, when the
|
||||
# package 'dnsmasq' is removed but not purged, even if the dnsmasq-base
|
||||
# package is still in place.
|
||||
test -e /usr/share/dnsmasq/installed-marker || exit 0
|
||||
|
||||
test -x $DAEMON || exit 0
|
||||
|
||||
# Provide skeleton LSB log functions for backports which don't have LSB functions.
|
||||
@@ -75,7 +81,7 @@ if [ ! "$RESOLV_CONF" ] &&
|
||||
[ "$IGNORE_RESOLVCONF" != "yes" ] &&
|
||||
[ -x /sbin/resolvconf ]
|
||||
then
|
||||
RESOLV_CONF=/var/run/dnsmasq/resolv.conf
|
||||
RESOLV_CONF=/run/dnsmasq/resolv.conf
|
||||
fi
|
||||
|
||||
for INTERFACE in $DNSMASQ_INTERFACE; do
|
||||
@@ -90,6 +96,24 @@ if [ ! "$DNSMASQ_USER" ]; then
|
||||
DNSMASQ_USER="dnsmasq"
|
||||
fi
|
||||
|
||||
# This tells dnsmasq to ignore DNS requests that don't come from a local network.
|
||||
# It's automatically ignored if --interface --except-interface, --listen-address
|
||||
# or --auth-server exist in the configuration, so for most installations, it will
|
||||
# have no effect, but for otherwise-unconfigured installations, it stops dnsmasq
|
||||
# from being vulnerable to DNS-reflection attacks.
|
||||
|
||||
DNSMASQ_OPTS="$DNSMASQ_OPTS --local-service"
|
||||
|
||||
# If the dns-root-data package is installed, then the trust anchors will be
|
||||
# available in $ROOT_DS, in BIND zone-file format. Reformat as dnsmasq
|
||||
# --trust-anchor options.
|
||||
|
||||
ROOT_DS="/usr/share/dns/root.ds"
|
||||
|
||||
if [ -f $ROOT_DS ]; then
|
||||
DNSMASQ_OPTS="$DNSMASQ_OPTS `env LC_ALL=C sed -rne "s/^([.a-zA-Z0-9]+)([[:space:]]+[0-9]+)*([[:space:]]+IN)*[[:space:]]+DS[[:space:]]+/--trust-anchor=\1,/;s/[[:space:]]+/,/gp" $ROOT_DS | tr '\n' ' '`"
|
||||
fi
|
||||
|
||||
start()
|
||||
{
|
||||
# Return
|
||||
@@ -97,16 +121,16 @@ start()
|
||||
# 1 if daemon was already running
|
||||
# 2 if daemon could not be started
|
||||
|
||||
# /var/run may be volatile, so we need to ensure that
|
||||
# /var/run/dnsmasq exists here as well as in postinst
|
||||
if [ ! -d /var/run/dnsmasq ]; then
|
||||
mkdir /var/run/dnsmasq || return 2
|
||||
chown dnsmasq:nogroup /var/run/dnsmasq || return 2
|
||||
# /run may be volatile, so we need to ensure that
|
||||
# /run/dnsmasq exists here as well as in postinst
|
||||
if [ ! -d /run/dnsmasq ]; then
|
||||
mkdir /run/dnsmasq || return 2
|
||||
chown dnsmasq:nogroup /run/dnsmasq || return 2
|
||||
fi
|
||||
|
||||
start-stop-daemon --start --quiet --pidfile /var/run/dnsmasq/$NAME.pid --exec $DAEMON --test > /dev/null || return 1
|
||||
start-stop-daemon --start --quiet --pidfile /var/run/dnsmasq/$NAME.pid --exec $DAEMON -- \
|
||||
-x /var/run/dnsmasq/$NAME.pid \
|
||||
start-stop-daemon --start --quiet --pidfile /run/dnsmasq/$NAME.pid --exec $DAEMON --test > /dev/null || return 1
|
||||
start-stop-daemon --start --quiet --pidfile /run/dnsmasq/$NAME.pid --exec $DAEMON -- \
|
||||
-x /run/dnsmasq/$NAME.pid \
|
||||
${MAILHOSTNAME:+ -m $MAILHOSTNAME} \
|
||||
${MAILTARGET:+ -t $MAILTARGET} \
|
||||
${DNSMASQ_USER:+ -u $DNSMASQ_USER} \
|
||||
@@ -130,6 +154,11 @@ start_resolvconf()
|
||||
[ $interface = lo ] && return
|
||||
done
|
||||
|
||||
# Also skip this if DNS functionality is disabled in /etc/dnsmasq.conf
|
||||
if grep -qs '^port=0' /etc/dnsmasq.conf; then
|
||||
return
|
||||
fi
|
||||
|
||||
if [ -x /sbin/resolvconf ] ; then
|
||||
echo "nameserver 127.0.0.1" | /sbin/resolvconf -a lo.$NAME
|
||||
fi
|
||||
@@ -143,10 +172,7 @@ stop()
|
||||
# 1 if daemon was already stopped
|
||||
# 2 if daemon could not be stopped
|
||||
# other if a failure occurred
|
||||
start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile /var/run/dnsmasq/$NAME.pid --name $NAME
|
||||
RETVAL="$?"
|
||||
[ "$RETVAL" = 2 ] && return 2
|
||||
return "$RETVAL"
|
||||
start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile /run/dnsmasq/$NAME.pid --name $NAME
|
||||
}
|
||||
|
||||
stop_resolvconf()
|
||||
@@ -164,9 +190,9 @@ status()
|
||||
# 1 if daemon is dead and pid file exists
|
||||
# 3 if daemon is not running
|
||||
# 4 if daemon status is unknown
|
||||
start-stop-daemon --start --quiet --pidfile /var/run/dnsmasq/$NAME.pid --exec $DAEMON --test > /dev/null
|
||||
start-stop-daemon --start --quiet --pidfile /run/dnsmasq/$NAME.pid --exec $DAEMON --test > /dev/null
|
||||
case "$?" in
|
||||
0) [ -e "/var/run/dnsmasq/$NAME.pid" ] && return 1 ; return 3 ;;
|
||||
0) [ -e "/run/dnsmasq/$NAME.pid" ] && return 1 ; return 3 ;;
|
||||
1) return 0 ;;
|
||||
*) return 4 ;;
|
||||
esac
|
||||
@@ -257,7 +283,7 @@ case "$1" in
|
||||
esac
|
||||
;;
|
||||
dump-stats)
|
||||
kill -s USR1 `cat /var/run/dnsmasq/$NAME.pid`
|
||||
kill -s USR1 `cat /run/dnsmasq/$NAME.pid`
|
||||
;;
|
||||
systemd-start-resolvconf)
|
||||
start_resolvconf
|
||||
@@ -266,9 +292,13 @@ case "$1" in
|
||||
stop_resolvconf
|
||||
;;
|
||||
systemd-exec)
|
||||
# --pid-file without argument disables writing a PIDfile, we don't need one with sytemd.
|
||||
# Enable DBus by default because we use DBus activation with systemd.
|
||||
exec $DAEMON --keep-in-foreground --pid-file --enable-dbus \
|
||||
# /run may be volatile, so we need to ensure that
|
||||
# /run/dnsmasq exists here as well as in postinst
|
||||
if [ ! -d /run/dnsmasq ]; then
|
||||
mkdir /run/dnsmasq || return 2
|
||||
chown dnsmasq:nogroup /run/dnsmasq || return 2
|
||||
fi
|
||||
exec $DAEMON -x /run/dnsmasq/$NAME.pid \
|
||||
${MAILHOSTNAME:+ -m $MAILHOSTNAME} \
|
||||
${MAILTARGET:+ -t $MAILTARGET} \
|
||||
${DNSMASQ_USER:+ -u $DNSMASQ_USER} \
|
||||
|
||||
2
debian/installed-marker
vendored
Normal file
2
debian/installed-marker
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
# This file indicates dnsmasq (and not just dnsmasq-base) is installed.
|
||||
# It is an implementation detail of the dnsmasq init script.
|
||||
3
debian/lintian-override
vendored
Normal file
3
debian/lintian-override
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
# dnsmasq-base and dnsmasq-base-lua are mutually exclusive and both
|
||||
# provide /usr/share/doc/dnsmasq-base
|
||||
dnsmasq-base-lua binary: usr-share-doc-symlink-without-dependency dnsmasq-base
|
||||
18
debian/postinst
vendored
18
debian/postinst
vendored
@@ -1,11 +1,27 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
# Code copied from dh_systemd_enable ----------------------
|
||||
# This will only remove masks created by d-s-h on package removal.
|
||||
deb-systemd-helper unmask dnsmasq.service >/dev/null || true
|
||||
|
||||
# was-enabled defaults to true, so new installations run enable.
|
||||
if deb-systemd-helper --quiet was-enabled dnsmasq.service; then
|
||||
# Enables the unit on first installation, creates new
|
||||
# symlinks on upgrades if the unit file has changed.
|
||||
deb-systemd-helper enable dnsmasq.service >/dev/null || true
|
||||
else
|
||||
# Update the statefile to add new symlinks (if any), which need to be
|
||||
# cleaned up on purge. Also remove old symlinks.
|
||||
deb-systemd-helper update-state dnsmasq.service >/dev/null || true
|
||||
fi
|
||||
# End code copied from dh_systemd_enable ------------------
|
||||
|
||||
if [ -x /etc/init.d/dnsmasq ]; then
|
||||
update-rc.d dnsmasq defaults 15 85 >/dev/null
|
||||
|
||||
if [ "$1" = "configure" ] || [ "$1" = "abort-upgrade" ]; then
|
||||
if [ -e /var/run/dnsmasq/dnsmasq.pid ]; then
|
||||
if [ -e /run/dnsmasq/dnsmasq.pid ]; then
|
||||
ACTION=restart
|
||||
else
|
||||
ACTION=start
|
||||
|
||||
16
debian/postrm
vendored
16
debian/postrm
vendored
@@ -4,3 +4,19 @@ set -e
|
||||
if [ purge = "$1" ]; then
|
||||
update-rc.d dnsmasq remove >/dev/null
|
||||
fi
|
||||
|
||||
# Code copied from dh_systemd_enable ----------------------
|
||||
if [ "$1" = "remove" ]; then
|
||||
if [ -x "/usr/bin/deb-systemd-helper" ]; then
|
||||
deb-systemd-helper mask dnsmasq.service >/dev/null
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$1" = "purge" ]; then
|
||||
if [ -x "/usr/bin/deb-systemd-helper" ]; then
|
||||
deb-systemd-helper purge dnsmasq.service >/dev/null
|
||||
deb-systemd-helper unmask dnsmasq.service >/dev/null
|
||||
fi
|
||||
fi
|
||||
# End code copied from dh_systemd_enable ------------------
|
||||
|
||||
|
||||
6
debian/readme
vendored
6
debian/readme
vendored
@@ -31,7 +31,7 @@ Notes on configuring dnsmasq as packaged for Debian.
|
||||
as the first nameserver address in /etc/resolv.conf.
|
||||
|
||||
(6) In the absence of resolvconf, dns-nameservers lines in
|
||||
/etc/network/interfaces are ignored. If you do do not use
|
||||
/etc/network/interfaces are ignored. If you do not use
|
||||
resolvconf, list 127.0.0.1 as the first nameserver address
|
||||
in /etc/resolv.conf and configure your nameservers using
|
||||
"server=<IP-address>" lines in /etc/dnsmasq.conf.
|
||||
@@ -54,7 +54,7 @@ Notes on configuring dnsmasq as packaged for Debian.
|
||||
nodhcp : omit DHCP support.
|
||||
nodhcp6 : omit DHCPv6 support.
|
||||
noscript : omit lease-change script support.
|
||||
use_lua : provide support for lease-change scripts written
|
||||
uselua : provide support for lease-change scripts written
|
||||
in Lua.
|
||||
noipv6 : omit IPv6 support.
|
||||
nodbus : omit DBus support.
|
||||
@@ -66,7 +66,7 @@ Notes on configuring dnsmasq as packaged for Debian.
|
||||
combined with noi18n to be effective.
|
||||
gitversion : set the version of the produced packages from the
|
||||
git-derived versioning information on the source,
|
||||
rather the the debian changelog.
|
||||
rather than the debian changelog.
|
||||
|
||||
(9) Dnsmasq comes as three packages - dnsmasq-utils, dnsmasq-base and
|
||||
dnsmasq. Dnsmasq-base provides the dnsmasq executable and
|
||||
|
||||
2
debian/resolvconf
vendored
2
debian/resolvconf
vendored
@@ -13,7 +13,7 @@
|
||||
|
||||
set -e
|
||||
|
||||
RUN_DIR="/var/run/dnsmasq"
|
||||
RUN_DIR="/run/dnsmasq"
|
||||
RSLVRLIST_FILE="${RUN_DIR}/resolv.conf"
|
||||
TMP_FILE="${RSLVRLIST_FILE}_new.$$"
|
||||
MY_NAME_FOR_RESOLVCONF="dnsmasq"
|
||||
|
||||
286
debian/rules
vendored
286
debian/rules
vendored
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/make -f
|
||||
# debian/rules file - for dnsmasq.
|
||||
# Copyright 2001-2011 by Simon Kelley
|
||||
# Copyright 2001-2018 by Simon Kelley
|
||||
# Based on the sample in the debian hello package which carries the following:
|
||||
# Copyright 1994,1995 by Ian Jackson.
|
||||
# I hereby give you perpetual unlimited permission to copy,
|
||||
@@ -11,17 +11,33 @@
|
||||
|
||||
package=dnsmasq-base
|
||||
|
||||
CFLAGS = $(shell export DEB_BUILD_OPTIONS=$(DEB_BUILD_OPTIONS); dpkg-buildflags --get CFLAGS)
|
||||
CFLAGS += $(shell dpkg-buildflags --get CPPFLAGS)
|
||||
dpkg_buildflags := DEB_BUILD_MAINT_OPTIONS="hardening=+all,+pie,+bindnow" dpkg-buildflags
|
||||
|
||||
CFLAGS = $(shell $(dpkg_buildflags) --get CFLAGS)
|
||||
CFLAGS += $(shell $(dpkg_buildflags) --get CPPFLAGS)
|
||||
CFLAGS += -Wall -W
|
||||
|
||||
LDFLAGS = $(shell dpkg-buildflags --get LDFLAGS)
|
||||
LDFLAGS = $(shell $(dpkg_buildflags) --get LDFLAGS)
|
||||
|
||||
DEB_COPTS = $(COPTS)
|
||||
|
||||
TARGET = install-i18n
|
||||
|
||||
DEB_BUILD_ARCH_OS := $(shell dpkg-architecture -qDEB_BUILD_ARCH_OS)
|
||||
DEB_HOST_ARCH_OS := $(shell dpkg-architecture -qDEB_HOST_ARCH_OS)
|
||||
DEB_HOST_GNU_TYPE := $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
|
||||
DEB_BUILD_GNU_TYPE := $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
|
||||
BUILD_DATE := $(shell dpkg-parsechangelog --show-field Date)
|
||||
|
||||
ifeq ($(origin CC),default)
|
||||
CC = $(DEB_HOST_GNU_TYPE)-gcc
|
||||
endif
|
||||
|
||||
# Support non-cross-builds on systems without gnu-triplet-binaries for pkg-config.
|
||||
ifeq ($(DEB_BUILD_GNU_TYPE),$(DEB_HOST_GNU_TYPE))
|
||||
PKG_CONFIG=pkg-config
|
||||
else
|
||||
PKG_CONFIG=$(DEB_HOST_GNU_TYPE)-pkg-config
|
||||
endif
|
||||
|
||||
# Force package version based on git tags.
|
||||
ifneq (,$(filter gitversion,$(DEB_BUILD_OPTIONS)))
|
||||
@@ -32,8 +48,12 @@ ifeq (,$(filter nodbus,$(DEB_BUILD_OPTIONS)))
|
||||
DEB_COPTS += -DHAVE_DBUS
|
||||
endif
|
||||
|
||||
ifeq (,$(filter noidn, $(DEB_BUILD_OPTIONS)))
|
||||
DEB_COPTS += -DHAVE_IDN
|
||||
endif
|
||||
|
||||
ifeq (,$(filter noconntrack,$(DEB_BUILD_OPTIONS)))
|
||||
ifeq ($(DEB_BUILD_ARCH_OS),linux)
|
||||
ifeq ($(DEB_HOST_ARCH_OS),linux)
|
||||
DEB_COPTS += -DHAVE_CONNTRACK
|
||||
endif
|
||||
endif
|
||||
@@ -68,9 +88,6 @@ endif
|
||||
|
||||
ifneq (,$(filter noi18n,$(DEB_BUILD_OPTIONS)))
|
||||
TARGET = install
|
||||
ifeq (,$(filter noidn, $(DEB_BUILD_OPTIONS)))
|
||||
DEB_COPTS += -DHAVE_IDN
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq (,$(filter uselua,$(DEB_BUILD_OPTIONS)))
|
||||
@@ -81,118 +98,175 @@ ifeq (,$(filter nodnssec,$(DEB_BUILD_OPTIONS)))
|
||||
DEB_COPTS += -DHAVE_DNSSEC
|
||||
endif
|
||||
|
||||
ifneq ($(DEB_HOST_ARCH_OS),linux)
|
||||
# For strlcpy in FreeBSD
|
||||
LDFLAGS += -lbsd
|
||||
endif
|
||||
|
||||
define build_tree
|
||||
rm -rf $1
|
||||
install -m 755 \
|
||||
-d $1/DEBIAN \
|
||||
-d $1/etc/dbus-1/system.d \
|
||||
-d $1/usr/share/doc/$(package) \
|
||||
-d $1/usr/share/doc/$(package)/examples \
|
||||
-d $1/usr/share/$(package) \
|
||||
-d $1/var/lib/misc
|
||||
|
||||
endef
|
||||
|
||||
define add_docs
|
||||
# Need to remove paypal links in Debian Package for policy reasons.
|
||||
sed -e /\<H2\>Donations/Q -e /icon.png/d doc.html -e /favicon.ico/d >$1/usr/share/doc/$(package)/doc.html
|
||||
echo "</BODY>" >>$1/usr/share/doc/$(package)/doc.html
|
||||
install -m 644 setup.html $1/usr/share/doc/$(package)/.
|
||||
install -m 644 dnsmasq.conf.example $1/usr/share/doc/$(package)/examples/.
|
||||
install -m 644 FAQ $1/usr/share/doc/$(package)/.
|
||||
gzip -9n $1/usr/share/doc/$(package)/FAQ
|
||||
install -m 644 CHANGELOG $1/usr/share/doc/$(package)/changelog
|
||||
gzip -9n $1/usr/share/doc/$(package)/changelog
|
||||
install -m 644 CHANGELOG.archive $1/usr/share/doc/$(package)/changelog.archive
|
||||
gzip -9n $1/usr/share/doc/$(package)/changelog.archive
|
||||
install -m 644 dbus/DBus-interface $1/usr/share/doc/$(package)/.
|
||||
gzip -9n $1/usr/share/doc/$(package)/DBus-interface
|
||||
gzip -9n $1/usr/share/man/man8/dnsmasq.8
|
||||
for f in $1/usr/share/man/*; do \
|
||||
if [ -f $$f/man8/dnsmasq.8 ]; then \
|
||||
gzip -9n $$f/man8/dnsmasq.8 ; \
|
||||
fi \
|
||||
done
|
||||
endef
|
||||
|
||||
define add_files
|
||||
install -m 644 trust-anchors.conf $1/usr/share/$(package)/.
|
||||
install -m 644 debian/dnsmasq-base.conffiles $1/DEBIAN/conffiles
|
||||
install -m 755 debian/dnsmasq-base.postinst $1/DEBIAN/postinst
|
||||
install -m 755 debian/dnsmasq-base.postrm $1/DEBIAN/postrm
|
||||
install -m 644 debian/changelog $1/usr/share/doc/$(package)/changelog.Debian
|
||||
gzip -9n $1/usr/share/doc/$(package)/changelog.Debian
|
||||
install -m 644 debian/readme $1/usr/share/doc/$(package)/README.Debian
|
||||
install -m 644 debian/copyright $1/usr/share/doc/$(package)/copyright
|
||||
install -m 644 debian/dbus.conf $1/etc/dbus-1/system.d/dnsmasq.conf
|
||||
endef
|
||||
|
||||
clean:
|
||||
$(checkdir)
|
||||
rm -rf debian/daemon debian/base debian/utils debian/*~ debian/files debian/substvars debian/utils-substvars
|
||||
make clean
|
||||
make -C contrib/wrt clean
|
||||
make BUILDDIR=debian/build/no-lua clean
|
||||
make BUILDDIR=debian/build/lua clean
|
||||
make -C contrib/lease-tools clean
|
||||
rm -rf debian/build debian/trees debian/*~ debian/files debian/substvars debian/utils-substvars
|
||||
|
||||
binary-indep: checkroot
|
||||
$(checkdir)
|
||||
rm -rf debian/daemon
|
||||
rm -rf debian/trees/daemon
|
||||
install -m 755 \
|
||||
-d debian/daemon/DEBIAN \
|
||||
-d debian/daemon/usr/share/doc \
|
||||
-d debian/daemon/etc/init.d \
|
||||
-d debian/daemon/etc/dnsmasq.d \
|
||||
-d debian/daemon/etc/resolvconf/update.d \
|
||||
-d debian/daemon/usr/lib/resolvconf/dpkg-event.d \
|
||||
-d debian/daemon/etc/default \
|
||||
-d debian/daemon/lib/systemd/system \
|
||||
-d debian/daemon/etc/insserv.conf.d
|
||||
install -m 644 debian/conffiles debian/daemon/DEBIAN
|
||||
install -m 755 debian/postinst debian/postrm debian/prerm debian/daemon/DEBIAN
|
||||
install -m 755 debian/init debian/daemon/etc/init.d/dnsmasq
|
||||
install -m 755 debian/resolvconf debian/daemon/etc/resolvconf/update.d/dnsmasq
|
||||
install -m 755 debian/resolvconf-package debian/daemon/usr/lib/resolvconf/dpkg-event.d/dnsmasq
|
||||
install -m 644 debian/default debian/daemon/etc/default/dnsmasq
|
||||
install -m 644 dnsmasq.conf.example debian/daemon/etc/dnsmasq.conf
|
||||
install -m 644 debian/readme.dnsmasq.d debian/daemon/etc/dnsmasq.d/README
|
||||
install -m 644 debian/systemd.service debian/daemon/lib/systemd/system/dnsmasq.service
|
||||
install -m 644 debian/insserv debian/daemon/etc/insserv.conf.d/dnsmasq
|
||||
ln -s $(package) debian/daemon/usr/share/doc/dnsmasq
|
||||
cd debian/daemon && find . -type f ! -regex '.*DEBIAN/.*' -printf '%P\0' | xargs -r0 md5sum > DEBIAN/md5sums
|
||||
dpkg-gencontrol $(PACKAGE_VERSION) -T -pdnsmasq -Pdebian/daemon
|
||||
chown -R root.root debian/daemon
|
||||
chmod -R g-ws debian/daemon
|
||||
dpkg --build debian/daemon ..
|
||||
-d debian/trees/daemon/DEBIAN \
|
||||
-d debian/trees/daemon/usr/share/doc \
|
||||
-d debian/trees/daemon/etc/init.d \
|
||||
-d debian/trees/daemon/etc/dnsmasq.d \
|
||||
-d debian/trees/daemon/etc/resolvconf/update.d \
|
||||
-d debian/trees/daemon/usr/lib/resolvconf/dpkg-event.d \
|
||||
-d debian/trees/daemon/usr/share/dnsmasq \
|
||||
-d debian/trees/daemon/etc/default \
|
||||
-d debian/trees/daemon/lib/systemd/system \
|
||||
-d debian/trees/daemon/etc/insserv.conf.d
|
||||
install -m 644 debian/conffiles debian/trees/daemon/DEBIAN
|
||||
install -m 755 debian/postinst debian/postrm debian/prerm debian/trees/daemon/DEBIAN
|
||||
install -m 755 debian/init debian/trees/daemon/etc/init.d/dnsmasq
|
||||
install -m 755 debian/resolvconf debian/trees/daemon/etc/resolvconf/update.d/dnsmasq
|
||||
install -m 755 debian/resolvconf-package debian/trees/daemon/usr/lib/resolvconf/dpkg-event.d/dnsmasq
|
||||
install -m 644 debian/installed-marker debian/trees/daemon/usr/share/dnsmasq
|
||||
install -m 644 debian/default debian/trees/daemon/etc/default/dnsmasq
|
||||
install -m 644 dnsmasq.conf.example debian/trees/daemon/etc/dnsmasq.conf
|
||||
install -m 644 debian/readme.dnsmasq.d debian/trees/daemon/etc/dnsmasq.d/README
|
||||
install -m 644 debian/systemd.service debian/trees/daemon/lib/systemd/system/dnsmasq.service
|
||||
install -m 644 debian/insserv debian/trees/daemon/etc/insserv.conf.d/dnsmasq
|
||||
ln -s $(package) debian/trees/daemon/usr/share/doc/dnsmasq
|
||||
cd debian/trees/daemon && find . -type f ! -regex '.*DEBIAN/.*' -printf '%P\0' | LC_ALL=C sort -z | xargs -r0 md5sum > DEBIAN/md5sums
|
||||
dpkg-gencontrol $(PACKAGE_VERSION) -T -pdnsmasq -Pdebian/trees/daemon
|
||||
find debian/trees/daemon -depth -newermt '$(BUILD_DATE)' -print0 | xargs -0r touch --no-dereference --date='$(BUILD_DATE)'
|
||||
chown -R root.root debian/trees/daemon
|
||||
chmod -R g-ws debian/trees/daemon
|
||||
dpkg --build debian/trees/daemon ..
|
||||
|
||||
binary-arch: checkroot
|
||||
$(checkdir)
|
||||
rm -rf debian/base
|
||||
install -m 755 \
|
||||
-d debian/base/DEBIAN \
|
||||
-d debian/base/etc/dbus-1/system.d \
|
||||
-d debian/base/usr/share/doc/$(package) \
|
||||
-d debian/base/usr/share/doc/$(package)/examples \
|
||||
-d debian/base/var/run \
|
||||
-d debian/base/usr/share/$(package) \
|
||||
-d debian/base/var/lib/misc
|
||||
make $(TARGET) PREFIX=/usr DESTDIR=`pwd`/debian/base CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" COPTS="$(DEB_COPTS)" CC=gcc
|
||||
$(call build_tree,debian/trees/base)
|
||||
make $(TARGET) BUILDDIR=debian/build/no-lua PREFIX=/usr DESTDIR=`pwd`/debian/trees/base CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" COPTS="$(DEB_COPTS)" CC=$(CC) PKG_CONFIG=$(PKG_CONFIG)
|
||||
ifeq (,$(findstring nodocs,$(DEB_BUILD_OPTIONS)))
|
||||
install -m 644 doc.html debian/base/usr/share/doc/$(package)/.
|
||||
install -m 644 setup.html debian/base/usr/share/doc/$(package)/.
|
||||
install -m 644 dnsmasq.conf.example debian/base/usr/share/doc/$(package)/examples/.
|
||||
install -m 644 trust-anchors.conf debian/base/usr/share/$(package)/.
|
||||
install -m 644 FAQ debian/base/usr/share/doc/$(package)/.
|
||||
gzip -9 debian/base/usr/share/doc/$(package)/FAQ
|
||||
install -m 644 CHANGELOG debian/base/usr/share/doc/$(package)/changelog
|
||||
gzip -9 debian/base/usr/share/doc/$(package)/changelog
|
||||
install -m 644 CHANGELOG.archive debian/base/usr/share/doc/$(package)/changelog.archive
|
||||
gzip -9 debian/base/usr/share/doc/$(package)/changelog.archive
|
||||
install -m 644 dbus/DBus-interface debian/base/usr/share/doc/$(package)/.
|
||||
gzip -9 debian/base/usr/share/doc/$(package)/DBus-interface
|
||||
$(call add_docs,debian/trees/base)
|
||||
else
|
||||
rm -rf debian/trees/base/usr/share/man
|
||||
endif
|
||||
install -m 644 debian/dnsmasq-base.conffiles debian/base/DEBIAN/conffiles
|
||||
install -m 755 debian/dnsmasq-base.postinst debian/base/DEBIAN/postinst
|
||||
install -m 755 debian/dnsmasq-base.postrm debian/base/DEBIAN/postrm
|
||||
install -m 644 debian/changelog debian/base/usr/share/doc/$(package)/changelog.Debian
|
||||
gzip -9 debian/base/usr/share/doc/$(package)/changelog.Debian
|
||||
install -m 644 debian/readme debian/base/usr/share/doc/$(package)/README.Debian
|
||||
install -m 644 debian/copyright debian/base/usr/share/doc/$(package)/copyright
|
||||
install -m 644 debian/dbus.conf debian/base/etc/dbus-1/system.d/dnsmasq.conf
|
||||
gzip -9 debian/base/usr/share/man/man8/dnsmasq.8
|
||||
for f in debian/base/usr/share/man/*; do \
|
||||
if [ -f $$f/man8/dnsmasq.8 ]; then \
|
||||
gzip -9 $$f/man8/dnsmasq.8 ; \
|
||||
fi \
|
||||
done
|
||||
$(call add_files,debian/trees/base)
|
||||
ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
|
||||
strip -R .note -R .comment debian/base/usr/sbin/dnsmasq
|
||||
$(DEB_HOST_GNU_TYPE)-strip -R .note -R .comment debian/trees/base/usr/sbin/dnsmasq
|
||||
endif
|
||||
cd debian/base && find . -type f ! -regex '.*DEBIAN/.*' -printf '%P\0' | xargs -r0 md5sum > DEBIAN/md5sums
|
||||
dpkg-shlibdeps --warnings=1 debian/base/usr/sbin/dnsmasq
|
||||
dpkg-gencontrol $(PACKAGE_VERSION) -pdnsmasq-base -Pdebian/base
|
||||
chown -R root.root debian/base
|
||||
chmod -R g-ws debian/base
|
||||
dpkg --build debian/base ..
|
||||
cd debian/trees/base && find . -type f ! -regex '.*DEBIAN/.*' -printf '%P\0' | LC_ALL=C sort -z | xargs -r0 md5sum > DEBIAN/md5sums
|
||||
dpkg-shlibdeps --warnings=1 debian/trees/base/usr/sbin/dnsmasq
|
||||
dpkg-gencontrol $(PACKAGE_VERSION) -pdnsmasq-base -Pdebian/trees/base
|
||||
find debian/trees/base -depth -newermt '$(BUILD_DATE)' -print0 | xargs -0r touch --no-dereference --date='$(BUILD_DATE)'
|
||||
chown -R root.root debian/trees/base
|
||||
chmod -R g-ws debian/trees/base
|
||||
dpkg --build debian/trees/base ..
|
||||
|
||||
ifeq ($(DEB_BUILD_ARCH_OS),linux)
|
||||
rm -rf debian/utils
|
||||
install -m 755 -d debian/utils/DEBIAN \
|
||||
-d debian/utils/usr/share/man/man1 \
|
||||
-d debian/utils/usr/bin \
|
||||
-d debian/utils/usr/share/doc/dnsmasq-utils
|
||||
make -C contrib/wrt PREFIX=/usr DESTDIR=`pwd`/debian/utils CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" COPTS="$(DEB_COPTS)" CC=gcc
|
||||
install -m 755 contrib/wrt/dhcp_release debian/utils/usr/bin/dhcp_release
|
||||
install -m 644 contrib/wrt/dhcp_release.1 debian/utils/usr/share/man/man1/dhcp_release.1
|
||||
gzip -9 debian/utils/usr/share/man/man1/dhcp_release.1
|
||||
install -m 755 contrib/wrt/dhcp_lease_time debian/utils/usr/bin/dhcp_lease_time
|
||||
install -m 644 contrib/wrt/dhcp_lease_time.1 debian/utils/usr/share/man/man1/dhcp_lease_time.1
|
||||
install -m 644 debian/copyright debian/utils/usr/share/doc/dnsmasq-utils/copyright
|
||||
install -m 644 debian/changelog debian/utils/usr/share/doc/dnsmasq-utils/changelog.Debian
|
||||
gzip -9 debian/utils/usr/share/doc/dnsmasq-utils/changelog.Debian
|
||||
gzip -9 debian/utils/usr/share/man/man1/dhcp_lease_time.1
|
||||
$(call build_tree,debian/trees/lua-base)
|
||||
make $(TARGET) BUILDDIR=debian/build/lua PREFIX=/usr DESTDIR=`pwd`/debian/trees/lua-base CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" COPTS="-DHAVE_LUASCRIPT $(DEB_COPTS)" CC=$(CC) PKG_CONFIG=$(PKG_CONFIG)
|
||||
ifeq (,$(findstring nodocs,$(DEB_BUILD_OPTIONS)))
|
||||
$(call add_docs,debian/trees/lua-base)
|
||||
else
|
||||
rm -rf debian/trees/lua-base/usr/share/man
|
||||
endif
|
||||
$(call add_files,debian/trees/lua-base)
|
||||
install -m 755 -d debian/trees/lua-base/usr/share/lintian/overrides
|
||||
install -m 644 debian/lintian-override debian/trees/lua-base/usr/share/lintian/overrides/dnsmasq-base-lua
|
||||
ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
|
||||
strip -R .note -R .comment debian/utils/usr/bin/dhcp_release
|
||||
strip -R .note -R .comment debian/utils/usr/bin/dhcp_lease_time
|
||||
$(DEB_HOST_GNU_TYPE)-strip -R .note -R .comment debian/trees/lua-base/usr/sbin/dnsmasq
|
||||
endif
|
||||
ln -s $(package) debian/trees/lua-base/usr/share/doc/dnsmasq-base-lua
|
||||
cd debian/trees/lua-base && find . -type f ! -regex '.*DEBIAN/.*' -printf '%P\0' | LC_ALL=C sort -z | xargs -r0 md5sum > DEBIAN/md5sums
|
||||
dpkg-shlibdeps --warnings=1 debian/trees/lua-base/usr/sbin/dnsmasq
|
||||
dpkg-gencontrol $(PACKAGE_VERSION) -pdnsmasq-base-lua -Pdebian/trees/lua-base
|
||||
find debian/trees/lua-base -depth -newermt '$(BUILD_DATE)' -print0 | xargs -0r touch --no-dereference --date='$(BUILD_DATE)'
|
||||
chown -R root.root debian/trees/lua-base
|
||||
chmod -R g-ws debian/trees/lua-base
|
||||
dpkg --build debian/trees/lua-base ..
|
||||
|
||||
|
||||
ifeq ($(DEB_HOST_ARCH_OS),linux)
|
||||
rm -rf debian/trees/utils
|
||||
install -m 755 -d debian/trees/utils/DEBIAN \
|
||||
-d debian/trees/utils/usr/bin \
|
||||
-d debian/trees/utils/usr/share/doc/dnsmasq-utils
|
||||
ifeq (,$(findstring nodocs,$(DEB_BUILD_OPTIONS)))
|
||||
install -m 755 -d debian/trees/utils/usr/share/man/man1
|
||||
endif
|
||||
make -C contrib/lease-tools PREFIX=/usr DESTDIR=`pwd`/debian/trees/utils CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" COPTS="$(DEB_COPTS)" CC=$(CC) PKG_CONFIG=$(PKG_CONFIG)
|
||||
install -m 755 contrib/lease-tools/dhcp_release debian/trees/utils/usr/bin/dhcp_release
|
||||
install -m 755 contrib/lease-tools/dhcp_release6 debian/trees/utils/usr/bin/dhcp_release6
|
||||
install -m 755 contrib/lease-tools/dhcp_lease_time debian/trees/utils/usr/bin/dhcp_lease_time
|
||||
ifeq (,$(findstring nodocs,$(DEB_BUILD_OPTIONS)))
|
||||
install -m 644 contrib/lease-tools/dhcp_release.1 debian/trees/utils/usr/share/man/man1/dhcp_release.1
|
||||
gzip -9n debian/trees/utils/usr/share/man/man1/dhcp_release.1
|
||||
install -m 644 contrib/lease-tools/dhcp_release6.1 debian/trees/utils/usr/share/man/man1/dhcp_release6.1
|
||||
gzip -9n debian/trees/utils/usr/share/man/man1/dhcp_release6.1
|
||||
install -m 644 contrib/lease-tools/dhcp_lease_time.1 debian/trees/utils/usr/share/man/man1/dhcp_lease_time.1
|
||||
gzip -9n debian/trees/utils/usr/share/man/man1/dhcp_lease_time.1
|
||||
endif
|
||||
install -m 644 debian/copyright debian/trees/utils/usr/share/doc/dnsmasq-utils/copyright
|
||||
install -m 644 debian/changelog debian/trees/utils/usr/share/doc/dnsmasq-utils/changelog.Debian
|
||||
gzip -9n debian/trees/utils/usr/share/doc/dnsmasq-utils/changelog.Debian
|
||||
ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
|
||||
$(DEB_HOST_GNU_TYPE)-strip -R .note -R .comment debian/trees/utils/usr/bin/dhcp_release
|
||||
$(DEB_HOST_GNU_TYPE)-strip -R .note -R .comment debian/trees/utils/usr/bin/dhcp_release6
|
||||
$(DEB_HOST_GNU_TYPE)-strip -R .note -R .comment debian/trees/utils/usr/bin/dhcp_lease_time
|
||||
endif
|
||||
cd debian/utils && find . -type f ! -regex '.*DEBIAN/.*' -printf '%P\0' | xargs -r0 md5sum > DEBIAN/md5sums
|
||||
dpkg-shlibdeps -Tdebian/utils-substvars debian/utils/usr/bin/dhcp_release debian/utils/usr/bin/dhcp_lease_time
|
||||
dpkg-gencontrol $(PACKAGE_VERSION) -Tdebian/utils-substvars -pdnsmasq-utils -Pdebian/utils
|
||||
chown -R root.root debian/utils
|
||||
chmod -R g-ws debian/utils
|
||||
dpkg --build debian/utils ..
|
||||
cd debian/trees/utils && find . -type f ! -regex '.*DEBIAN/.*' -printf '%P\0' | LC_ALL=C sort -z | xargs -r0 md5sum > DEBIAN/md5sums
|
||||
dpkg-shlibdeps -Tdebian/utils-substvars debian/trees/utils/usr/bin/dhcp_release debian/trees/utils/usr/bin/dhcp_release6 debian/trees/utils/usr/bin/dhcp_lease_time
|
||||
dpkg-gencontrol $(PACKAGE_VERSION) -Tdebian/utils-substvars -pdnsmasq-utils -Pdebian/trees/utils
|
||||
find debian/trees/utils -depth -newermt '$(BUILD_DATE)' -print0 | xargs -0r touch --no-dereference --date='$(BUILD_DATE)'
|
||||
chown -R root.root debian/trees/utils
|
||||
chmod -R g-ws debian/trees/utils
|
||||
dpkg --build debian/trees/utils ..
|
||||
endif
|
||||
|
||||
define checkdir
|
||||
|
||||
18
debian/systemd.service
vendored
18
debian/systemd.service
vendored
@@ -1,9 +1,13 @@
|
||||
[Unit]
|
||||
Description=A lightweight DHCP and caching DNS server
|
||||
Description=dnsmasq - A lightweight DHCP and caching DNS server
|
||||
Requires=network.target
|
||||
Wants=nss-lookup.target
|
||||
Before=nss-lookup.target
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=dbus
|
||||
BusName=uk.org.thekelleys.dnsmasq
|
||||
Type=forking
|
||||
PIDFile=/run/dnsmasq/dnsmasq.pid
|
||||
|
||||
# Test the config file and refuse starting if it is not valid.
|
||||
ExecStartPre=/usr/sbin/dnsmasq --test
|
||||
@@ -11,16 +15,10 @@ ExecStartPre=/usr/sbin/dnsmasq --test
|
||||
# We run dnsmasq via the /etc/init.d/dnsmasq script which acts as a
|
||||
# wrapper picking up extra configuration files and then execs dnsmasq
|
||||
# itself, when called with the "systemd-exec" function.
|
||||
#
|
||||
# It also adds the command-line flags
|
||||
# --keep-in-foreground --pid-file --enable-dbus
|
||||
# to disable writing a pid-file (not needed with systemd) and
|
||||
# enable DBus by default because we use DBus activation.
|
||||
#
|
||||
ExecStart=/etc/init.d/dnsmasq systemd-exec
|
||||
|
||||
# The systemd-*-resolvconf functions configure (and deconfigure)
|
||||
# resolvconf to work with the dnsmasq DNS server. They're called liek
|
||||
# resolvconf to work with the dnsmasq DNS server. They're called like
|
||||
# this to get correct error handling (ie don't start-resolvconf if the
|
||||
# dnsmasq daemon fails to start.
|
||||
ExecStartPost=/etc/init.d/dnsmasq systemd-start-resolvconf
|
||||
|
||||
@@ -25,6 +25,14 @@
|
||||
#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,
|
||||
@@ -82,7 +90,7 @@
|
||||
# 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 a interface with that
|
||||
# 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
|
||||
|
||||
@@ -181,7 +189,7 @@
|
||||
# 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 alogrithm.
|
||||
# IPv6 address calculated using the SLAAC algorithm.
|
||||
#dhcp-range=1234::, ra-names
|
||||
|
||||
# Do Router Advertisements, BUT NOT DHCP for this subnet.
|
||||
@@ -202,7 +210,7 @@
|
||||
#dhcp-range=1234::, ra-stateless, ra-names
|
||||
|
||||
# Do router advertisements for all subnets where we're doing DHCPv6
|
||||
# Unless overriden by ra-stateless, ra-names, et al, the router
|
||||
# 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.
|
||||
@@ -243,6 +251,13 @@
|
||||
# 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
|
||||
@@ -273,7 +288,7 @@
|
||||
# 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 the they [] around the IPv6 address are obilgatory.
|
||||
# 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
|
||||
@@ -337,6 +352,14 @@
|
||||
# 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
|
||||
#dhcp-option=42,0.0.0.0
|
||||
@@ -413,22 +436,22 @@
|
||||
#dhcp-option-force=211,30i
|
||||
|
||||
# Set the boot filename for netboot/PXE. You will only need
|
||||
# this is you want to boot machines over the network and you will need
|
||||
# a TFTP server; either dnsmasq's built in TFTP server or an
|
||||
# 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 Etherboot gPXE. The idea is to send two different
|
||||
# filenames, the first loads gPXE, and the second tells gPXE what to
|
||||
# load. The dhcp-match sets the gpxe tag for requests from gPXE.
|
||||
#dhcp-match=set:gpxe,175 # gPXE sends a 175 option.
|
||||
#dhcp-boot=tag:!gpxe,undionly.kpxe
|
||||
#dhcp-boot=mybootimage
|
||||
# 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 Etherboot gPXE. All the options are
|
||||
# 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
|
||||
@@ -478,6 +501,9 @@
|
||||
# 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
|
||||
@@ -499,7 +525,7 @@
|
||||
# (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 fasion. This facility can be used to
|
||||
# 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
|
||||
|
||||
@@ -521,6 +547,14 @@
|
||||
# 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
|
||||
@@ -632,3 +666,9 @@
|
||||
# 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
|
||||
|
||||
141
doc.html
141
doc.html
@@ -1,8 +1,7 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE> Dnsmasq - a DNS forwarder for NAT firewalls.</TITLE>
|
||||
<link rel="icon"
|
||||
href="http://www.thekelleys.org.uk/dnsmasq/images/favicon.ico">
|
||||
<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">
|
||||
<table width="100%" border="0" cellpadding="0" cellspacing="0">
|
||||
@@ -11,82 +10,48 @@
|
||||
<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.
|
||||
|
||||
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/TFTP/PXE for network booting of diskless machines.
|
||||
<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 smallish network (up to
|
||||
1000 clients is known to work) where low
|
||||
resource use and ease of configuration are important.
|
||||
<P>
|
||||
Supported platforms include Linux (with glibc and uclibc), Android, *BSD,
|
||||
Solaris and Mac OS X.
|
||||
Dnsmasq is included in at least the following Linux distributions:
|
||||
Gentoo, Debian, Slackware, Suse, Fedora,
|
||||
Smoothwall, IP-Cop, floppyfw, Firebox, LEAF, Freesco, fli4l,
|
||||
CoyoteLinux, Endian Firewall and
|
||||
Clarkconnect. It is also available as FreeBSD, OpenBSD and NetBSD ports and is used in
|
||||
Linksys wireless routers (dd-wrt, openwrt and the stock firmware) 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
|
||||
its 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 and SRV 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>
|
||||
<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>Get code.</H2>
|
||||
|
||||
@@ -101,16 +66,36 @@ 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>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>.
|
||||
|
||||
<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>
|
||||
|
||||
|
||||
736
man/dnsmasq.8
736
man/dnsmasq.8
File diff suppressed because it is too large
Load Diff
@@ -478,7 +478,8 @@ la traza reversa direcci
|
||||
.TP
|
||||
.B \-c, --cache-size=<tamaño de caché>
|
||||
Fijar el tamaño del caché de dnsmasq. El predeterminado es 150 nombres.
|
||||
Fijar el tamaño a cero deshabilita el caché.
|
||||
Fijar el tamaño a cero deshabilita el caché. Nota: el gran tamaño de
|
||||
caché afecta el rendimiento.
|
||||
.TP
|
||||
.B \-N, --no-negcache
|
||||
Deshabilitar caché negativo. El caché negativo le permite a dnsmasq
|
||||
@@ -1062,10 +1063,14 @@ esta opci
|
||||
cuando hay cambios hechos a el client-id y tiempos de arriendo y vencimiento.
|
||||
.TP
|
||||
.B --bridge-interface=<nombre de interface>,<alias>[,<alias>]
|
||||
Tratar paquetes de pedidos DHCP que llegan a cualquiera de las interfaces <alias>
|
||||
como si hubieran llegado a la interface <nombre de interface>. Esta opción
|
||||
es necesaria al usar bridging estilo viejo en plataformas BSD, dado a que
|
||||
los paquetes llegan a interfaces tap que no tienen una dirección IP.
|
||||
Tratar paquetes de pedidos DHCP (v4 y v6) y de IPv6 Router Solicit que
|
||||
llegan a cualquiera de las interfaces <alias> como si hubieran llegado
|
||||
a la interface <nombre de interface>. Esta opción permite que dnsmasq
|
||||
puede proporcionar los servicios DHCP y RA a través de interfaces
|
||||
ethernet sin dirección y sin puente; por ejemplo en un nodo de cálculo
|
||||
de OpenStack, donde cada una de esas interfaces es una interfaz TAP
|
||||
para una máquina virtual, o al usar bridging estilo viejo en
|
||||
plataformas BSD.
|
||||
.TP
|
||||
.B \-s, --domain=<dominio>[,<rango de IPs>]
|
||||
Especifica los dominios DNS para el servidor DHCP. Dominios pueden ser
|
||||
|
||||
266
man/fr/dnsmasq.8
266
man/fr/dnsmasq.8
@@ -10,7 +10,7 @@ est un serveur à faible empreinte mémoire faisant DNS, TFTP, PXE, annonces de
|
||||
routeurs et DHCP. Il offre à la fois les services DNS et DHCP pour un réseau
|
||||
local (LAN).
|
||||
.PP
|
||||
Dnsmasq accepte les requêtes DNS et y réponds soit en utilisant un petit cache
|
||||
Dnsmasq accepte les requêtes DNS et y répond soit en utilisant un petit cache
|
||||
local, soit en effectuant une requête à un serveur DNS récursif externe (par
|
||||
exemple celui de votre fournisseur d'accès internet). Il charge le contenu du
|
||||
fichier /etc/hosts afin que les noms locaux n'apparaissant pas dans les DNS
|
||||
@@ -19,25 +19,25 @@ pour les hôtes présents dans le service DHCP. Il peut aussi agir en temps que
|
||||
serveur DNS faisant autorité pour un ou plusieurs domaines, permettant à des
|
||||
noms locaux d'apparaitre dans le DNS global.
|
||||
.PP
|
||||
Le serveur DHCP Dnsmasq DHCP supporte les définitions d'adresses statiques et les
|
||||
Le serveur DHCP de Dnsmasq supporte les définitions d'adresses statiques et les
|
||||
réseaux multiples. Il fournit par défaut un jeu raisonnable de paramètres DHCP,
|
||||
et peut être configuré pour fournir n'importe quelle option DHCP.
|
||||
Il inclut un serveur TFTP sécurisé en lecture seule permettant le démarrage via
|
||||
le réseau/PXE de clients DHCP et supporte également le protocole BOOTP. Le
|
||||
support PXE est complet, et comprend un mode proxy permettant de fournir des
|
||||
informations PXE aux clients alors que l'allocation DHCP est effectuée par un
|
||||
autre serveur.
|
||||
informations PXE aux clients alors que l'allocation d'adresse via DHCP est
|
||||
effectuée par un autre serveur.
|
||||
.PP
|
||||
Le serveur DHCPv6 de dnsmasq possède non seulement les mêmes fonctionalités
|
||||
Le serveur DHCPv6 de dnsmasq possède non seulement les mêmes fonctionnalités
|
||||
que le serveur DHCPv4, mais aussi le support des annonces de routeurs ainsi
|
||||
qu'une fonctionalité permettant l'addition de ressources AAAA pour des
|
||||
qu'une fonctionnalité permettant l'addition de ressources AAAA pour des
|
||||
clients utilisant DHCPv4 et la configuration IPv6 sans état (stateless
|
||||
autoconfiguration).
|
||||
Il inclut le support d'allocations d'adresses (à la fois en DHCPv6 et en
|
||||
annonces de routeurs - RA) pour des sous-réseaux dynamiquement délégués via
|
||||
une délégation de préfixe DHCPv6.
|
||||
.PP
|
||||
Dnsmasq est developpé pour de petits systèmes embarqués. It tends à avoir
|
||||
Dnsmasq est développé pour de petits systèmes embarqués. Il tend à avoir
|
||||
l'empreinte mémoire la plus faible possible pour les fonctions supportées,
|
||||
et permet d'exclure les fonctions inutiles du binaire compilé.
|
||||
.SH OPTIONS
|
||||
@@ -46,16 +46,23 @@ Dans ce cas, la fonction correspondante sera désactivée. Par exemple
|
||||
.B --pid-file=
|
||||
(sans paramètre après le =) désactive l'écriture du fichier PID.
|
||||
Sur BSD, à moins que le logiciel ne soit compilé avec la bibliothèque GNU
|
||||
getopt, la forme longue des options ne fonctionne pas en ligne de commande; Elle
|
||||
getopt, la forme longue des options ne fonctionne pas en ligne de commande; elle
|
||||
est toujours supportée dans le fichier de configuration.
|
||||
.TP
|
||||
.B --test
|
||||
Vérifie la syntaxe du ou des fichiers de configurations. Se termine avec le
|
||||
Vérifie la syntaxe du ou des fichiers de configuration. Se termine avec le
|
||||
code de retour 0 si tout est OK, ou un code différent de 0 dans le cas
|
||||
contraire. Ne démarre pas Dnsmasq.
|
||||
.TP
|
||||
.B \-w, --help
|
||||
Affiche toutes les options de ligne de commande.
|
||||
.B --help dhcp
|
||||
affiche les options de configuration connues pour DHCPv4, et
|
||||
.B --help dhcp6
|
||||
affiche les options de configuration connues pour DHCPv6.
|
||||
.TP
|
||||
.B \-h, --no-hosts
|
||||
Ne pas charger les noms du fichier /etc/hosts.
|
||||
Ne pas charger les noms d'hôtes du fichier /etc/hosts.
|
||||
.TP
|
||||
.B \-H, --addn-hosts=<fichier>
|
||||
Fichiers d'hôtes additionnels. Lire le fichier spécifié en plus de /etc/hosts.
|
||||
@@ -68,7 +75,7 @@ fichiers contenus dans ce répertoire.
|
||||
.B \-E, --expand-hosts
|
||||
Ajoute le nom de domaine aux noms simples (ne contenant pas de point dans le
|
||||
nom) contenus dans le fichier /etc/hosts, de la même façon que pour le service
|
||||
DHCP. Notez que cela ne s'applique pas au nom de domaine dans les CNAME, les
|
||||
DHCP. Notez que cela ne s'applique pas aux noms de domaine dans les CNAME, les
|
||||
enregistrements PTR, TXT, etc...
|
||||
.TP
|
||||
.B \-T, --local-ttl=<durée>
|
||||
@@ -86,7 +93,7 @@ Les réponses négatives provenant des serveurs amonts contiennent normalement
|
||||
une information de durée de vie (time-to-live) dans les enregistrements SOA,
|
||||
information dont dnsmasq se sert pour mettre la réponse en cache. Si la réponse
|
||||
du serveur amont omet cette information, dnsmasq ne cache pas la réponse. Cette
|
||||
option permet de doner une valeur de durée de vie par défaut (en secondes) que
|
||||
option permet de donner une valeur de durée de vie par défaut (en secondes) que
|
||||
dnsmasq utilise pour mettre les réponses négatives dans son cache, même en
|
||||
l'absence d'enregistrement SOA.
|
||||
.TP
|
||||
@@ -194,7 +201,7 @@ au dessus de la valeur spécifiée. Utile pour des systèmes derrière des dispo
|
||||
garde-barrières ("firewalls").
|
||||
.TP
|
||||
.B \-i, --interface=<nom d'interface>
|
||||
N'écouter que sur l'interface réseau spécifiée. Dnsmasq aujoute automatiquement
|
||||
N'écouter que sur l'interface réseau spécifiée. Dnsmasq ajoute automatiquement
|
||||
l'interface locale ("loopback") à la liste des interfaces lorsque l'option
|
||||
.B --interface
|
||||
est utilisée.
|
||||
@@ -205,13 +212,13 @@ ou
|
||||
n'est donnée, Dnsmasq écoutera sur toutes les interfaces disponibles sauf
|
||||
celle(s) spécifiée(s) par l'option
|
||||
.B --except-interface.
|
||||
Les alias d'interfaces IP (e-g "eth1:0") ne peuvent être utilisés ni avec
|
||||
Les alias d'interfaces IP (par exemple "eth1:0") ne peuvent être utilisés ni avec
|
||||
.B --interface
|
||||
ni
|
||||
.B \--except-interface.
|
||||
Utiliser l'option
|
||||
.B --listen-address
|
||||
à la place. Un simple joker, consistant d'un '*' final, peut-être utilisé dans
|
||||
à la place. Un simple joker, consistant en un '*' final, peut être utilisé dans
|
||||
les options
|
||||
.B \--interface
|
||||
et
|
||||
@@ -229,10 +236,10 @@ sont fournies n'importe pas, et que l'option
|
||||
.B --except-interface
|
||||
l'emporte toujours sur les autres.
|
||||
.TP
|
||||
.B --auth-server=<domaine>,<interface>|<addresse IP>
|
||||
.B --auth-server=<domaine>,<interface>|<adresse IP>
|
||||
Active le mode DNS faisant autorité pour les requêtes arrivant sur cette
|
||||
interface ou sur cette adresse. Noter que l'interface ou l'adresse n'ont
|
||||
pas besoin d'être mentionées ni dans
|
||||
pas besoin d'être mentionnées ni dans
|
||||
.B --interface
|
||||
ni dans
|
||||
.B --listen-address
|
||||
@@ -253,7 +260,7 @@ Ecouter sur la ou les adresse(s) IP spécifiée(s). Les options
|
||||
.B \--interface
|
||||
et
|
||||
.B \--listen-address
|
||||
peuvent-être spécifiées simultanément, auquel cas un jeu d'interfaces et
|
||||
peuvent être spécifiées simultanément, auquel cas un jeu d'interfaces et
|
||||
d'adresses seront utilisées. Notez que si
|
||||
aucune option
|
||||
.B \--interface
|
||||
@@ -265,7 +272,7 @@ nécessaire de fournir explicitement son adresse IP, 127.0.0.1 via l'option
|
||||
.B \--listen-address.
|
||||
.TP
|
||||
.B \-z, --bind-interfaces
|
||||
Sur les systèmes qui le supporte, Dnsmasq s'associe avec l'interface joker
|
||||
Sur les systèmes qui le supportent, Dnsmasq s'associe avec l'interface joker
|
||||
("wildcard"), même lorsqu'il ne doit écouter que sur certaines interfaces. Par
|
||||
la suite, il rejette les requêtes auxquelles il ne doit pas répondre. Cette
|
||||
situation présente l'avantage de fonctionner même lorsque les interfaces vont
|
||||
@@ -302,7 +309,7 @@ le réseau auquel ils sont attachés). Cette possibilité est actuellement limit
|
||||
.TP
|
||||
.B \-b, --bogus-priv
|
||||
Fausse résolution inverse pour les réseaux privés. Toutes les requêtes DNS
|
||||
inverses pour des adresses IP privées (ie 192.168.x.x, etc...) qui ne sont pas
|
||||
inverses pour des adresses IP privées (192.168.x.x, etc...) qui ne sont pas
|
||||
trouvées dans /etc/hosts ou dans le fichier de baux DHCP se voient retournées
|
||||
une réponse "pas de tel domaine" ("no such domain") au lieu d'être transmises
|
||||
aux serveurs de nom amont ("upstream server").
|
||||
@@ -317,7 +324,7 @@ modifiera 1.2.3.56 en 6.7.8.56 et 1.2.3.67 en 6.7.8.67.
|
||||
Cette fonctionnalité correspond à ce que les routeurs Cisco PIX appellent
|
||||
"bidouillage DNS" ("DNS doctoring"). Si l'ancienne IP est donnée sous la forme
|
||||
d'une gamme d'adresses, alors seules les adresses dans cette gamme seront
|
||||
réecrites, et non le sous-réseau dans son ensemble. Ainsi,
|
||||
réécrites, et non le sous-réseau dans son ensemble. Ainsi,
|
||||
.B --alias=192.168.0.10-192.168.0.40,10.0.0.0,255.255.255.0
|
||||
fait correspondre 192.168.0.10->192.168.0.40 à 10.0.0.10->10.0.0.40
|
||||
.TP
|
||||
@@ -380,7 +387,7 @@ effectuer ses requêtes à tous les serveurs disponibles. Le résultat renvoyé
|
||||
au client sera celui fournit par le premier serveur ayant répondu.
|
||||
.TP
|
||||
.B --stop-dns-rebind
|
||||
Rejete (et enregistre dans le journal d'activité) les adresses dans la gamme
|
||||
Rejette (et enregistre dans le journal d'activité) les adresses dans la gamme
|
||||
d'adresses IP privée (au sens RFC1918) qui pourraient être renvoyées par les
|
||||
serveurs amonts suite à une résolution de nom. Cela bloque les attaques cherchant
|
||||
à détourner de leur usage les logiciels de navigation web ('browser') en s'en
|
||||
@@ -389,13 +396,13 @@ servant pour découvrir les machines situées sur le réseau local.
|
||||
.B --rebind-localhost-ok
|
||||
Exclue 127.0.0/8 des vérifications de réassociation DNS. Cette gamme d'adresses
|
||||
est retournée par les serveurs Realtime Blackhole (RBL, utilisés dans la
|
||||
lutte contre le spam), la bloquer peut entraîner des disfonctionnements de ces
|
||||
lutte contre le spam), la bloquer peut entraîner des dysfonctionnements de ces
|
||||
services.
|
||||
.TP
|
||||
.B --rebind-domain-ok=[<domaine>]|[[/<domaine>/[<domaine>/]
|
||||
Ne pas détecter ni bloquer les actions de type dns-rebind pour ces domaines.
|
||||
Cette option peut prendre comme valeur soit un nom de domaine soit plusieurs
|
||||
noms de domains entourés par des '/', selon une syntaxe similaire à l'option
|
||||
noms de domaine entourés par des '/', selon une syntaxe similaire à l'option
|
||||
--server, c-à-d :
|
||||
.B --rebind-domain-ok=/domaine1/domaine2/domaine3/
|
||||
.TP
|
||||
@@ -474,7 +481,7 @@ serveur de nom. Il doit s'agir d'une des adresses IP appartenant à la machine s
|
||||
laquelle tourne Dnsmasq ou sinon la ligne sera ignorée et une erreur sera
|
||||
consignée dans le journal des événements, ou alors d'un nom d'interface. Si un nom
|
||||
d'interface est donné, alors les requêtes vers le serveur de nom seront envoyées
|
||||
depuis cette interface; si une adresse ip est donnée, alors l'adresse source de
|
||||
depuis cette interface; si une adresse IP est donnée, alors l'adresse source de
|
||||
la requête sera l'adresse en question. L'option query-port est ignorée pour tous
|
||||
les serveurs ayant une adresse source spécifiée, mais il est possible de la donner
|
||||
directement dans la spécification de l'adresse source. Forcer les requêtes à être
|
||||
@@ -510,7 +517,7 @@ d'IP netfilter (ipset) indiqués. Domaines et sous-domaines sont résolus de la
|
||||
même façon que pour --address. Ces groupes d'IP doivent déjà exister. Voir
|
||||
ipset(8) pour plus de détails.
|
||||
.TP
|
||||
.B \-m, --mx-host=<nom de l'hôte>[[,<nom du MX>],<préference>]
|
||||
.B \-m, --mx-host=<nom de l'hôte>[[,<nom du MX>],<préférence>]
|
||||
Spécifie un enregistrement de type MX pour <nom de l'hôte> retournant le nom
|
||||
donné dans <nom du MX> (s'il est présent), ou sinon le nom spécifié dans
|
||||
l'option
|
||||
@@ -612,7 +619,7 @@ l'enregistrement est donnée dans les données hexadécimales, qui peuvent
|
||||
être de la forme 01:23:45, 01 23 45,+012345 ou n'importe quelle combinaison.
|
||||
.TP
|
||||
.B --interface-name=<nom>,<interface>
|
||||
Définit un entregistrement DNS associant le nom avec l'adresse primaire sur
|
||||
Définit un enregistrement DNS associant le nom avec l'adresse primaire sur
|
||||
l'interface donnée en argument. Cette option spécifie un enregistrement de type
|
||||
A pour le nom donné en argument de la même façon que s'il était défini par une
|
||||
ligne de /etc/hosts, sauf que l'adresse n'est pas constante mais dépendante de
|
||||
@@ -638,7 +645,7 @@ IPv6 pouvant commencer par '::', mais les noms DNS ne pouvant pas commencer
|
||||
par '-', si aucun préfixe n'est donné, un zéro est ajouté en début de nom.
|
||||
Ainsi, ::1 devient 0--1.
|
||||
|
||||
La plage d'adresses peut-être de la forme
|
||||
La plage d'adresses peut être de la forme
|
||||
<adresse IP>,<adresse IP> ou <adresse IP>/<masque réseau>
|
||||
.TP
|
||||
.B --add-mac
|
||||
@@ -647,7 +654,7 @@ amonts. Cela peut être utilisé dans un but de filtrage DNS par les serveurs
|
||||
amonts. L'adresse MAC peut uniquement être ajoutée si le requêteur est sur le
|
||||
même sous-réseau que le serveur dnsmasq. Veuillez noter que le mécanisme
|
||||
utilisé pour effectuer cela (une option EDNS0) n'est pas encore standardisée,
|
||||
aussi cette fonctionalité doit être considérée comme expérimentale. Notez
|
||||
aussi cette fonctionnalité doit être considérée comme expérimentale. Notez
|
||||
également qu'exposer les adresses MAC de la sorte peut avoir des implications
|
||||
en termes de sécurité et de vie privée. L'avertissement donné pour --add-subnet
|
||||
s'applique également ici.
|
||||
@@ -659,19 +666,20 @@ longueur du préfixe : 32 (ou 128 dans le cas d'IPv6) transmet la totalité
|
||||
de l'adresse, 0 n'en transmet aucun mais marque néanmoins la requête ce qui
|
||||
fait qu'aucun serveur amont ne rajoutera d'adresse client. La valeur par
|
||||
défaut est zéro et pour IPv4 et pour IPv6. A noter que les serveurs amonts
|
||||
peuvent-être configurés pour retourner des valeurs différentes en fonction
|
||||
peuvent être configurés pour retourner des valeurs différentes en fonction
|
||||
de cette information mais que le cache de dnsmasq n'en tient pas compte.
|
||||
Si une instance de dnsmasq est configurée de telle maniêre que des valeurs
|
||||
différentes pourraient-être rencontrés, alors le cache devrait être désactivé.
|
||||
Si une instance de dnsmasq est configurée de telle manière que des valeurs
|
||||
différentes pourraient être rencontrées, alors le cache devrait être désactivé.
|
||||
.TP
|
||||
.B \-c, --cache-size=<taille>
|
||||
Définit la taille du cache de Dnsmasq. La valeur par défaut est de 150 noms.
|
||||
Définir une valeur de zéro désactive le cache.
|
||||
Définir une valeur de zéro désactive le cache. Remarque: la taille importante
|
||||
du cache a un impact sur les performances.
|
||||
.TP
|
||||
.B \-N, --no-negcache
|
||||
Désactive le "cache négatif". Le "cache négatif" permet à Dnsmasq de se souvenir
|
||||
des réponses de type "no such domain" fournies par les serveurs DNS en amont et
|
||||
de fournir les réponses sans avoir à re-transmettre les requêtes aux serveurs
|
||||
de fournir les réponses sans avoir à retransmettre les requêtes aux serveurs
|
||||
amont.
|
||||
.TP
|
||||
.B \-0, --dns-forward-max=<nombre de requêtes>
|
||||
@@ -683,17 +691,17 @@ son journal des requêtes, ce qui peut générer un nombre important de requête
|
||||
simultanées.
|
||||
.TP
|
||||
.B --proxy-dnssec
|
||||
Un resolveur sur une machine cliente peut effectuer la validation DNSSEC de
|
||||
Un résolveur sur une machine cliente peut effectuer la validation DNSSEC de
|
||||
deux façons : il peut effectuer lui-même les opérations de chiffrements sur
|
||||
la réponse reçue, ou il peut laisser le serveur récursif amont faire la
|
||||
validation et positionner un drapeau dans la réponse au cas où celle-ci est
|
||||
correcte. Dnsmasq n'est pas un validateur DNSSEC, aussi il ne peut effectuer
|
||||
la validation comme un serveur de nom récursif, cependant il peut retransmettre
|
||||
les résultats de validation de ses serveurs amonts. Cette option permet
|
||||
l'activation de cette fonctionalité. Vous ne devriez utiliser cela que si vous
|
||||
l'activation de cette fonctionnalité. Vous ne devriez utiliser cela que si vous
|
||||
faites confiance aux serveurs amonts
|
||||
.I ainsi que le réseau entre vous et eux.
|
||||
Si vous utilisez le premier mode DNSSEC, la validation par le resolveur des
|
||||
Si vous utilisez le premier mode DNSSEC, la validation par le résolveur des
|
||||
clients, cette option n'est pas requise. Dnsmasq retourne toujours toutes les
|
||||
données nécessaires par un client pour effectuer la validation lui-même.
|
||||
.TP
|
||||
@@ -703,12 +711,12 @@ Définie une zone DNS pour laquelle dnsmasq agit en temps que serveur faisant
|
||||
autorité. Les enregistrements DNS définis localement et correspondant à ce
|
||||
domaine seront fournis. Les enregistrements A et AAAA doivent se situer dans
|
||||
l'un des sous-réseaux définis, ou dans un réseau correspondant à une plage DHCP
|
||||
(ce comportement peut-être désactivé par
|
||||
(ce comportement peut être désactivé par
|
||||
.B constructor-noauth:
|
||||
). Le ou les sous-réseaux sont également utilisé(s) pour définir les domaines
|
||||
in-addr.arpa et ipv6.arpa servant à l'interrogation DNS inverse. Si la longueur
|
||||
in-addr.arpa et ip6.arpa servant à l'interrogation DNS inverse. Si la longueur
|
||||
de préfixe n'est pas spécifiée, elle sera par défaut de 24 pour IPv4 et 64 pour
|
||||
IPv6. Dans le cas d'IPv4, la longueur du masque de réseau devrait-être de 8, 16
|
||||
IPv6. Dans le cas d'IPv4, la longueur du masque de réseau devrait être de 8, 16
|
||||
ou 24, sauf si en cas de mise en place d'une délégation de la zone in-addr.arpa
|
||||
conforme au RFC 2317.
|
||||
.TP
|
||||
@@ -719,7 +727,7 @@ optionnel, les valeurs par défaut devant convenir à la majorité des cas.
|
||||
.TP
|
||||
.B --auth-sec-servers=<domaine>[,<domaine>[,<domaine>...]]
|
||||
Spécifie un ou plusieurs serveur de nom secondaires pour une zone pour
|
||||
laquelle dnsmasq fait autorité. Ces serveurs doivent-être configurés pour
|
||||
laquelle dnsmasq fait autorité. Ces serveurs doivent être configurés pour
|
||||
récupérer auprès de dnsmasq les informations liées à la zone au travers d'un
|
||||
transfert de zone, et répondre aux requêtes pour toutes les zones pour
|
||||
lesquelles dnsmasq fait autorité.
|
||||
@@ -733,7 +741,7 @@ seront acceptées pour tous les serveurs secondaires.
|
||||
.B --conntrack
|
||||
Lis le marquage de suivi de connexion Linux associé aux requêtes DNS entrantes
|
||||
et positionne la même marque au trafic amont utilisé pour répondre à ces
|
||||
requétes. Cela permet au trafic généré par Dnsmasq d'étre associé aux requêtes
|
||||
requêtes. Cela permet au trafic généré par Dnsmasq d'être associé aux requêtes
|
||||
l'ayant déclenché, ce qui est pratique pour la gestion de la bande passante
|
||||
(accounting) et le filtrage (firewall). Dnsmasq doit pour cela être compilé
|
||||
avec le support conntrack, le noyau doit également inclure conntrack et être
|
||||
@@ -742,7 +750,7 @@ configuré pour cela. Cette option ne peut pas être combinée avec
|
||||
.TP
|
||||
.B \-F, --dhcp-range=[tag:<label>[,tag:<label>],][set:<label>],]<adresse de début>[,<adresse de fin>][,<mode>][,<masque de réseau>[,<broadcast>]][,<durée de bail>]
|
||||
.TP
|
||||
.B \-F, --dhcp-range=[tag:<label>[,tag:<label>],][set:<label>],]<addresse IPv6 de début>[,<adresse IPv6 de fin>|constructor:<interface>][,<mode>][,<longueur de préfixe>][,<durée de bail>]
|
||||
.B \-F, --dhcp-range=[tag:<label>[,tag:<label>],][set:<label>],]<adresse IPv6 de début>[,<adresse IPv6 de fin>|constructor:<interface>][,<mode>][,<longueur de préfixe>][,<durée de bail>]
|
||||
|
||||
Active le serveur DHCP. Les adresses seront données dans la plage comprise entre
|
||||
<adresse de début> et <adresse de fin> et à partir des adresses définies
|
||||
@@ -755,7 +763,7 @@ durée indéterminée. Si aucune valeur n'est donnée, une durée de bail par d
|
||||
de une heure est appliquée. La valeur minimum pour un bail DHCP est de 2
|
||||
minutes.
|
||||
|
||||
Pour les plages IPv6, la durée de bail peut-être égale au mot-clef "deprecated"
|
||||
Pour les plages IPv6, la durée de bail peut être égale au mot-clef "deprecated"
|
||||
(obsolète); Cela positionne la durée de vie préférée envoyée dans les baux DHCP
|
||||
ou les annonces routeurs à zéro, ce qui incite les clients à utiliser d'autres
|
||||
adresses autant que possible, pour toute nouvelle connexion, en préalable à
|
||||
@@ -795,7 +803,7 @@ adresses assignées à l'interface. Par exemple
|
||||
provoque la recherche d'adresses de la forme <réseau>::1 sur eth0 et crée une
|
||||
plage allant de <réseau>::1 à <réseau>:400. Si une interface est assignée à
|
||||
plus d'un réseau, les plages correspondantes seront automatiquement créées,
|
||||
rendues obsolètes puis supprimées lorsque l'adress est rendue obsolète puis
|
||||
rendues obsolètes puis supprimées lorsque l'adresse est rendue obsolète puis
|
||||
supprimée. Le nom de l'interface peut être spécifié avec un caractère joker '*'
|
||||
final.
|
||||
|
||||
@@ -809,7 +817,7 @@ obsolètes ne conviennent pas.
|
||||
|
||||
Si une plage dhcp-range est uniquement utilisée pour du DHCP sans-état
|
||||
("stateless") ou de l'autoconfiguration sans état ("SLAAC"), alors l'adresse
|
||||
peut-être indiquée sous la forme '::'
|
||||
peut être indiquée sous la forme '::'
|
||||
|
||||
.B --dhcp-range=::,constructor:eth0
|
||||
|
||||
@@ -851,8 +859,8 @@ et
|
||||
.B pxe-service
|
||||
pour plus de détails).
|
||||
|
||||
Pour IPv6, le mode peut-être une combinaison des valeurs
|
||||
.B ra-only, slaac, ra-names, ra-stateless.
|
||||
Pour IPv6, le mode peut être une combinaison des valeurs
|
||||
.B ra-only, slaac, ra-names, ra-stateless, off-link.
|
||||
|
||||
.B ra-only
|
||||
indique à dnsmasq de n'effectuer que des annonces de routeur (Router
|
||||
@@ -883,11 +891,14 @@ connectés (et non ceux pour lesquels DHCP se fait via relai), et ne
|
||||
fonctionnera pas si un hôte utilise les "extensions de vie privée"
|
||||
("privacy extensions").
|
||||
.B ra-names
|
||||
peut-être combiné avec
|
||||
peut être combiné avec
|
||||
.B ra-stateless
|
||||
et
|
||||
.B slaac.
|
||||
|
||||
.B off-link
|
||||
indique à dnsmasq d'annoncer le préfixe sans le bit L (sur lien).
|
||||
|
||||
.TP
|
||||
.B \-G, --dhcp-host=[<adresse matérielle>][,id:<identifiant client>|*][,set:<label>][,<adresse IP>][,<nom d'hôte>][,<durée de bail>][,ignore]
|
||||
Spécifie les paramètres DHCP relatifs à un hôte. Cela permet à une machine
|
||||
@@ -911,7 +922,7 @@ sous-réseau qu'une plage dhcp-range valide. Pour les sous-réseaux qui n'ont pa
|
||||
besoin d'adresses dynamiquement allouées, utiliser le mot-clef "static" dans la
|
||||
déclaration de plage d'adresses dhcp-range.
|
||||
|
||||
Il est possible d'utiliser des identifiants clients (appellé "DUID client" dans
|
||||
Il est possible d'utiliser des identifiants clients (appelés "DUID client" dans
|
||||
le monde IPv6) plutôt que des adresses matérielles pour identifier les hôtes,
|
||||
en préfixant ceux-ci par 'id:'. Ainsi,
|
||||
.B --dhcp-host=id:01:02:03:04,.....
|
||||
@@ -923,7 +934,7 @@ ceci :
|
||||
Un seul
|
||||
.B dhcp-host
|
||||
peut contenir une adresse IPv4, une adresse IPv6, ou les deux en même temps.
|
||||
Les adresses IPv6 doivent-être mises entre crochets comme suit :
|
||||
Les adresses IPv6 doivent être mises entre crochets comme suit :
|
||||
.B --dhcp-host=laptop,[1234::56]
|
||||
Les adresses IPv6 peuvent ne contenir que la partie identifiant de client :
|
||||
.B --dhcp-host=laptop,[::56]
|
||||
@@ -942,7 +953,7 @@ identifiant client mais pas les autres.
|
||||
Si un nom apparaît dans /etc/hosts, l'adresse associée peut être allouée à un
|
||||
bail DHCP mais seulement si une option
|
||||
.B --dhcp-host
|
||||
spécifiant le nom existe par ailleurs. Seul un nom d'hôte peut-être donné dans
|
||||
spécifiant le nom existe par ailleurs. Seul un nom d'hôte peut être donné dans
|
||||
une option
|
||||
.B dhcp-host
|
||||
, mais les alias sont possibles au travers de l'utilisation des CNAMEs. (Voir
|
||||
@@ -970,7 +981,7 @@ Les adresses ethernet (mais pas les identifiants clients) peuvent être définie
|
||||
avec des octets joker, ainsi par exemple
|
||||
.B --dhcp-host=00:20:e0:3b:13:*,ignore
|
||||
demande à Dnsmasq d'ignorer une gamme d'adresses matérielles. Il est à noter
|
||||
que "*" doit-être précédé d'un caractère d'échappement ou mis entre guillemets
|
||||
que "*" doit être précédé d'un caractère d'échappement ou mis entre guillemets
|
||||
lorsque spécifié en option de ligne de commande, mais pas dans le fichier de
|
||||
configuration.
|
||||
|
||||
@@ -1056,14 +1067,14 @@ qu'aux réseaux dont tous les labels coïncident avec ceux de la requête.
|
||||
Un traitement spécial est effectué sur les chaînes de caractères fournies pour
|
||||
l'option 119, conformément à la RFC 3397. Les chaînes de caractères ou les
|
||||
adresses IP sous forme de 4 chiffres séparés par des points donnés en arguments
|
||||
de l'option 120 sont traités conforméments à la RFC 3361. Les adresses IP sous
|
||||
de l'option 120 sont traités conformément à la RFC 3361. Les adresses IP sous
|
||||
forme de 4 chiffres séparés par des points suivies par une barre montante "/",
|
||||
puis une taille de masque sont encodés conforméments à la RFC 3442.
|
||||
puis une taille de masque sont encodés conformément à la RFC 3442.
|
||||
|
||||
Les options IPv6 sont fournies en utilisant le mot-clef
|
||||
.B option6:
|
||||
suivi par le numéro d'option ou le nom d'option. L'espace de nommage des options
|
||||
IPv6 est disjint de l'espace de nommage des options IPv4. Les adresses IPv6
|
||||
IPv6 est disjoint de l'espace de nommage des options IPv4. Les adresses IPv6
|
||||
en option doivent être entourées de crochets, comme par exemple :
|
||||
.B --dhcp-option=option6:ntp-server,[1234::56]
|
||||
|
||||
@@ -1072,7 +1083,7 @@ adéquat sont envoyées pour un numéro d'option donné, il est tout à fait pos
|
||||
de persuader Dnsmasq de générer des paquets DHCP illégaux par une utilisation
|
||||
incorrecte de cette option. Lorsque la valeur est un nombre décimal, Dnsmasq
|
||||
doit déterminer la taille des données. Cela est fait en examinant le numéro de
|
||||
l'option et/ou la valeur, mais peut-être évité en rajoutant un suffixe d'une
|
||||
l'option et/ou la valeur, mais peut être évité en rajoutant un suffixe d'une
|
||||
lettre comme suit :
|
||||
b = un octet, s = 2 octets, i = 4 octets. Cela sert essentiellement pour des
|
||||
options encapsulées de classes de vendeurs (voir plus bas), pour lesquelles
|
||||
@@ -1085,7 +1096,7 @@ d'une chaîne de caractères comme nom de serveur TFTP, il est nécessaire de fa
|
||||
comme suit :
|
||||
.B --dhcp-option=66,"1.2.3.4"
|
||||
|
||||
Les options encapsulées de classes de vendeurs peuvent-être aussi spécifiées
|
||||
Les options encapsulées de classes de vendeurs peuvent être aussi spécifiées
|
||||
(pour IPv4 seulement) en utilisant
|
||||
.B --dhcp-option
|
||||
: par exemple
|
||||
@@ -1102,7 +1113,7 @@ par le client. Il est possible d'omettre complètement une classe de vendeur :
|
||||
.B --dhcp-option=vendor:,1,0.0.0.0
|
||||
Dans ce cas l'option encapsulée est toujours envoyée.
|
||||
|
||||
En IPv4, les options peuvent-être encapsulées au sein d'autres options :
|
||||
En IPv4, les options peuvent être encapsulées au sein d'autres options :
|
||||
par exemple
|
||||
.B --dhcp-option=encap:175, 190, "iscsi-client0"
|
||||
enverra l'option 175, au sein de laquelle se trouve l'option 190.
|
||||
@@ -1125,7 +1136,7 @@ une option encapsulée.
|
||||
Cela fonctionne exactement de la même façon que
|
||||
.B --dhcp-option
|
||||
sauf que cette option sera toujours envoyée, même si le client ne la demande pas
|
||||
dans la liste de paramêtres requis. Cela est parfois nécessaire, par exemple lors
|
||||
dans la liste de paramètres requis. Cela est parfois nécessaire, par exemple lors
|
||||
de la fourniture d'options à PXELinux.
|
||||
.TP
|
||||
.B --dhcp-no-override
|
||||
@@ -1146,10 +1157,10 @@ Toutes les requêtes DHCP arrivant sur cette interface seront relayées au
|
||||
serveur DHCP distant correspondant à l'adresse de serveur indiquée. Il est
|
||||
possible de relayer depuis une unique adresse locale vers différents serveurs
|
||||
distant en spécifiant plusieurs fois l'option dhcp-relay avec la même adresse
|
||||
locale et différentes adresses de serveur. L'adresse de serveur doit-être
|
||||
sous forme numérique. Dans le cas de DHCPv6, l'adresse de serveur peut-être
|
||||
locale et différentes adresses de serveur. L'adresse de serveur doit être
|
||||
sous forme numérique. Dans le cas de DHCPv6, l'adresse de serveur peut être
|
||||
l'adresse de multicast ff05::1:3 correspondant à tous les serveurs DHCP. Dans
|
||||
ce cas, l'interface doit-étre spécifiée et ne peut comporter de caractère
|
||||
ce cas, l'interface doit être spécifiée et ne peut comporter de caractère
|
||||
joker. Elle sera utilisée pour indiquer l'interface à partir de laquelle le
|
||||
multicast pourra atteindre le serveur DHCP.
|
||||
|
||||
@@ -1178,14 +1189,14 @@ vice-versa.
|
||||
Associe une chaîne de classe de vendeur à un label. La plupart
|
||||
des clients DHCP fournissent une "classe de vendeur" ("vendor class") qui
|
||||
représente, d'une certaine façon, le type d'hôte. Cette option associe des
|
||||
classes de vendeur à des labels, de telle sorte que des options DHCP peuvent-être
|
||||
fournie de manière sélective aux différentes classes d'hôtes. Par exemple,
|
||||
classes de vendeur à des labels, de telle sorte que des options DHCP peuvent être
|
||||
fournies de manière sélective aux différentes classes d'hôtes. Par exemple,
|
||||
.B dhcp-vendorclass=set:printers,Hewlett-Packard JetDirect
|
||||
ou
|
||||
.B dhcp-vendorclass=printers,Hewlett-Packard JetDirect
|
||||
permet de n'allouer des options qu'aux imprimantes HP de la manière suivante :
|
||||
.B --dhcp-option=tag:printers,3,192.168.4.4
|
||||
La chaîne de caractères de la classe de vendeur founie en argument est cherchée
|
||||
La chaîne de caractères de la classe de vendeur fournie en argument est cherchée
|
||||
en temps que sous-chaîne de caractères au sein de la classe de vendeur fournie
|
||||
par le client, de façon à permettre la recherche d'un sous-ensemble de la chaîne
|
||||
de caractères ("fuzzy matching"). Le préfixe set: est optionnel mais autorisé
|
||||
@@ -1215,7 +1226,7 @@ matérielle coïncide avec les critères définis.
|
||||
.TP
|
||||
.B --dhcp-circuitid=set:<label>,<identifiant de circuit>, --dhcp-remoteid=set:<label>,<identifiant distant>
|
||||
Associe des options de relais DHCP issus de la RFC3046 à des labels.
|
||||
Cette information peut-être fournie par des relais DHCP. L'identifiant
|
||||
Cette information peut être fournie par des relais DHCP. L'identifiant
|
||||
de circuit ou l'identifiant distant est normalement fourni sous la forme d'une
|
||||
chaîne de valeurs hexadécimales séparées par des ":", mais il est également
|
||||
possible qu'elle le soit sous la forme d'une simple chaîne de caractères. Si
|
||||
@@ -1228,7 +1239,7 @@ est supporté en IPv6 (mais non dhcp-circuitid).
|
||||
(IPv4 et IPv6) Associe des options de relais DHCP issues de la RFC3993 à des
|
||||
labels.
|
||||
.TP
|
||||
.B --dhcp-proxy[=<adresse ip>]......
|
||||
.B --dhcp-proxy[=<adresse IP>]......
|
||||
(IPv4 seulement) Un agent relai DHCP normal est uniquement utilisé pour faire
|
||||
suivre les éléments initiaux de l'interaction avec le serveur DHCP. Une fois
|
||||
que le client est configuré, il communique directement avec le serveur. Cela
|
||||
@@ -1249,7 +1260,7 @@ interactions avec les relais dont l'adresse est dans la liste seront affectées.
|
||||
Si aucune valeur n'est spécifiée, associe le label si le client
|
||||
envoie une option DHCP avec le numéro ou le nom spécifié. Lorsqu'une valeur est
|
||||
fournie, positionne le label seulement dans le cas où l'option est fournie et
|
||||
correspond à la valeur. La valeur peut-être de la forme "01:ff:*:02", auquel
|
||||
correspond à la valeur. La valeur peut être de la forme "01:ff:*:02", auquel
|
||||
cas le début de l'option doit correspondre (en respectant les jokers). La
|
||||
valeur peut aussi être de la même forme que dans
|
||||
.B dhcp-option
|
||||
@@ -1259,14 +1270,14 @@ valeur peut aussi être de la même forme que dans
|
||||
--dhcp-match=set:efi-ia32,option:client-arch,6
|
||||
|
||||
spécifie le label "efi-ia32" si le numéro 6 apparaît dnas la liste
|
||||
d'architectures envoyé par le client au sein de l'option 93. (se réferer
|
||||
d'architectures envoyé par le client au sein de l'option 93. (se référer
|
||||
au RFC 4578 pour plus de détails). Si la valeur est un chaine de caractères,
|
||||
celle-ci est recherchée (correspondance en temps que sous-chaîne).
|
||||
|
||||
Pour la forme particulière vi-encap:<numéro d'entreprise>, la comparaison se
|
||||
fait avec les classes de vendeur "identifiant de vendeur" ("vendor-identifying
|
||||
vendor classes") pour l'entreprise dont le numéro est fourni en option.
|
||||
Veuillez vous réferer à la RFC 3925 pour plus de détail.
|
||||
Veuillez vous référer à la RFC 3925 pour plus de détails.
|
||||
.TP
|
||||
.B --tag-if=set:<label>[,set:<label>[,tag:<label>[,tag:<label>]]]
|
||||
Effectue une opération booléenne sur les labels. Si tous les labels
|
||||
@@ -1277,7 +1288,7 @@ Si aucun tag:<label> n'est spécifié, alors tous les labels fournis par
|
||||
set:<label> sont positionnés.
|
||||
N'importe quel nombre de set: ou tag: peuvent être fournis, et l'ordre est sans
|
||||
importance.
|
||||
Les lignes tag-if sont executées dans l'ordre, ce qui fait que si un label dans
|
||||
Les lignes tag-if sont exécutées dans l'ordre, ce qui fait que si un label dans
|
||||
tag:<label> est un label positionné par une rêgle
|
||||
.B tag-if,
|
||||
la ligne qui positionne le label doit précéder celle qui le teste.
|
||||
@@ -1317,17 +1328,17 @@ le cas de certains vieux clients BOOTP.
|
||||
(IPv4 seulement) Spécifie les options BOOTP devant être retournées par le
|
||||
serveur DHCP. Le nom de serveur ainsi que l'adresse sont optionnels : s'ils
|
||||
ne sont pas fournis, le nom est laissé vide et l'adresse fournie est celle de
|
||||
la machine sur laquelle s'exécute Dnsmasq. Si Dnsmasq founit un service TFTP (voir
|
||||
la machine sur laquelle s'exécute Dnsmasq. Si Dnsmasq fournit un service TFTP (voir
|
||||
.B --enable-tftp
|
||||
), alors seul un nom de fichier est requis ici pour permettre un démarrage par
|
||||
le réseau.
|
||||
Si d'éventuels labels sont fournis, ils doivent coïncider avec
|
||||
ceux du client pour que cet élement de configuration lui soit envoyé.
|
||||
ceux du client pour que cet élément de configuration lui soit envoyé.
|
||||
Une adresse de serveur TFTP peut être spécifiée à la place de l'adresse IP,
|
||||
sous la forme d'un nom de domaine qui sera cherché dans le fichier /etc/hosts.
|
||||
Ce nom peut être associé dans /etc/hosts avec plusieurs adresses IP, auquel cas
|
||||
celles-ci seront utilisées tour à tour (algorithme round-robin).
|
||||
Cela peut-être utiliser pour équilibrer la charge tftp sur plusieurs serveurs.
|
||||
Cela peut être utilisé pour équilibrer la charge tftp sur plusieurs serveurs.
|
||||
.TP
|
||||
.B --dhcp-sequential-ip
|
||||
Dnsmasq est conçu pour choisir l'adresse IP des clients DHCP en utilisant
|
||||
@@ -1354,7 +1365,7 @@ Ceci spécifie l'option de démarrage qui apparaitra dans un menu de démarrage
|
||||
PXE. <CSA> est le type du système client. Seuls des types de services valides
|
||||
apparaitront dans un menu. Les types connus sont x86PC, PC98, IA64_EFI, Alpha,
|
||||
Arc_x86, Intel_Lean_Client, IA32_EFI, BC_EFI, Xscale_EFI et X86-64_EFI;
|
||||
D'autres types peuvent-être spécifiés sous la forme d'une valeur entière. Le
|
||||
D'autres types peuvent être spécifiés sous la forme d'une valeur entière. Le
|
||||
paramètre après le texte correspondant à l'entrée dans le menu peut être un nom
|
||||
de fichier, auquel cas Dnsmasq agit comme un serveur de démarrage et indique au
|
||||
client PXE qu'il faut télécharger ce fichier via TFTP, soit depuis ce serveur
|
||||
@@ -1373,7 +1384,7 @@ démarrage n'est fournie (ou qu'une valeur de 0 est donnée pour le type de
|
||||
service), alors l'entrée de menu provoque l'interruption du démarrage par
|
||||
le réseau et la poursuite du démarrage sur un média local. L'adresse de serveur
|
||||
peut être donnée sous la forme de nom de domaine qui est recherché dans
|
||||
/etc/hosts. Ce nom peut-être associé à plusieurs adresses IP, qui dans ce cas
|
||||
/etc/hosts. Ce nom peut être associé à plusieurs adresses IP, qui dans ce cas
|
||||
sont utilisées à tour de rôle (en "round-robin").
|
||||
.TP
|
||||
.B --pxe-prompt=[tag:<label>,]<invite>[,<délai>]
|
||||
@@ -1432,7 +1443,7 @@ Utiliser cette option avec précaution, une adresse allouée à un client BOOTP
|
||||
étant perpétuelle, et de fait n'est plus disponibles pour d'autres hôtes. Si
|
||||
aucun argument n'est donné, alors cette option permet une allocation dynamique
|
||||
dans tous les cas. Si des arguments sont spécifiés, alors l'allocation ne se
|
||||
fait que lorsque tous les identifiants coïncident. Il est possible de répeter
|
||||
fait que lorsque tous les identifiants coïncident. Il est possible de répéter
|
||||
cette option avec plusieurs jeux d'arguments.
|
||||
.TP
|
||||
.B \-5, --no-ping
|
||||
@@ -1557,7 +1568,7 @@ Tous les descripteurs de fichiers sont fermés, sauf stdin, stdout et stderr qui
|
||||
sont ouverts sur /dev/null (sauf en mode déverminage).
|
||||
|
||||
Le script n'est pas lancé de manière concurrente : au plus une instance du
|
||||
script est executée à la fois (dnsmasq attends qu'une instance de script se
|
||||
script est exécutée à la fois (dnsmasq attend qu'une instance de script se
|
||||
termine avant de lancer la suivante). Les changements dans la base des baux
|
||||
nécessitant le lancement du script sont placé en attente dans une queue jusqu'à
|
||||
terminaison d'une instance du script en cours. Si cette mise en queue fait que
|
||||
@@ -1572,7 +1583,7 @@ le script sera invoqué avec une action "old" pour tous les baux existants.
|
||||
|
||||
Il existe deux autres actions pouvant apparaître comme argument au script :
|
||||
"init" et "tftp". D'autres sont susceptibles d'être rajoutées dans le futur,
|
||||
aussi les scripts devraient-être écrits de sorte à ignorer les actions
|
||||
aussi les scripts devraient être écrits de sorte à ignorer les actions
|
||||
inconnues. "init" est décrite ci-dessous dans
|
||||
.B --leasefile-ro.
|
||||
L'action "tftp" est invoquée lorsqu'un transfert de fichier TFTP s'est
|
||||
@@ -1585,7 +1596,7 @@ Spécifie un script écrit en Lua, devant être exécuté lorsque des baux sont
|
||||
créés, détruits ou modifiés. Pour utiliser cette option, dnsmasq doit être
|
||||
compilé avec avec le support de Lua. L'interpréteur Lua est initialisé une
|
||||
seule fois, lorsque dnsmasq démarre, ce qui fait que les variables globales
|
||||
persistent entre les évênements liés aux baux. Le code Lua doit définir une
|
||||
persistent entre les événements liés aux baux. Le code Lua doit définir une
|
||||
fonction
|
||||
.B lease
|
||||
et peut fournir des fonctions
|
||||
@@ -1634,7 +1645,7 @@ et
|
||||
.B --dhcp-scriptuser
|
||||
Spécifie l'utilisateur sous lequel le script shell lease-change ou le script
|
||||
doivent être exécutés. La valeur par défaut correspond à l'utilisateur root
|
||||
mais peut-être changée par le biais de cette option.
|
||||
mais peut être changée par le biais de cette option.
|
||||
.TP
|
||||
.B \-9, --leasefile-ro
|
||||
Supprimer complètement l'usage du fichier servant de base de donnée pour les
|
||||
@@ -1646,8 +1657,8 @@ biais de l'option
|
||||
être complètement gérée par le script sur un stockage externe. En addition aux
|
||||
actions décrites dans
|
||||
.B --dhcp-script,
|
||||
le script de changement d'état de bail est appellé une fois, au lancement de
|
||||
Dnsmasq, avec pour seul argument "init". Lorsqu'appellé de la sorte, le script
|
||||
le script de changement d'état de bail est appelé une fois, au lancement de
|
||||
Dnsmasq, avec pour seul argument "init". Lorsqu'appelé de la sorte, le script
|
||||
doit fournir l'état de la base de baux, dans le format de fichier de baux de
|
||||
Dnsmasq, sur sa sortie standard (stdout) et retourner un code de retour de 0.
|
||||
Positionner cette option provoque également une invocation du script de
|
||||
@@ -1655,11 +1666,14 @@ changement d'état de bail à chaque changement de l'identifiant de client, de
|
||||
longueur de bail ou de date d'expiration.
|
||||
.TP
|
||||
.B --bridge-interface=<interface>,<alias>[,<alias>]
|
||||
Traiter les requêtes DHCP arrivant sur n'importe laquelle des interfaces <alias>
|
||||
comme si elles arrivaient de l'interface <interface>. Cette option est
|
||||
nécessaire lors de l'utilisation de pont ethernet "ancien mode" sur plate-forme
|
||||
BSD, puisque dans ce cas les paquets arrivent sur des interfaces "tap" n'ont
|
||||
pas d'adresse IP.
|
||||
Traiter les requêtes DHCP (v4 et v6) et IPv6 Router Solicit arrivant
|
||||
sur n'importe laquelle des interfaces <alias> comme si elles
|
||||
arrivaient de l'interface <interface>. Cette option permet à dnsmasq
|
||||
de fournir les service DHCP et RA sur les interfaces ethernet non
|
||||
adressés et non pontés; par exemple sur un hôte de calcul d'OpenStack
|
||||
où chaque telle interface est une interface TAP à une machine
|
||||
virtuelle, ou lors de l'utilisation de pont ethernet "ancien mode" sur
|
||||
plate-forme BSD. Chaque <alias> peut finir avec un simple '*' joker.
|
||||
.TP
|
||||
.B \-s, --domain=<domaine>[,<gamme d'adresses>[,local]]
|
||||
Spécifie le domaine du serveur DHCP. Le domaine peut être donné de manière
|
||||
@@ -1686,20 +1700,20 @@ positionné à la première valeur de la directive "search" du fichier
|
||||
/etc/resolv.conf (ou équivalent).
|
||||
|
||||
La gamme d'adresses peut être de la forme
|
||||
<adresse ip>,<adresse ip> ou <adresse ip>/<masque de réseau> voire une simple
|
||||
<adresse ip>. Voir
|
||||
<adresse IP>,<adresse IP> ou <adresse IP>/<masque de réseau> voire une simple
|
||||
<adresse IP>. Voir
|
||||
.B --dhcp-fqdn
|
||||
qui peut changer le comportement de dnsmasq relatif aux domaines.
|
||||
|
||||
Si la gamme d'adresse est fournie sous la forme
|
||||
<adresse ip>/<taille de réseau>, alors le drapeau "local" peut-être rajouté
|
||||
qui a pour effect d'ajouter --local-declarations aux requêtes DNS directes et
|
||||
<adresse IP>/<taille de réseau>, alors le drapeau "local" peut être rajouté
|
||||
qui a pour effet d'ajouter --local-declarations aux requêtes DNS directes et
|
||||
inverses. C-à-d
|
||||
.B --domain=thekelleys.org.uk,192.168.0.0/24,local
|
||||
est identique à
|
||||
.B --domain=thekelleys.org.uk,192.168.0.0/24
|
||||
--local=/thekelleys.org.uk/ --local=/0.168.192.in-addr.arpa/
|
||||
La taille de réseau doit-être de 8, 16 ou 24 pour être valide.
|
||||
La taille de réseau doit être de 8, 16 ou 24 pour être valide.
|
||||
.TP
|
||||
.B --dhcp-fqdn
|
||||
Dans le mode par défaut, dnsmasq insère les noms non-qualifiés des clients
|
||||
@@ -1711,8 +1725,8 @@ ce nom est transféré au nouveau client. Si
|
||||
est spécifié, ce comportement change : les noms non qualifiés ne sont plus
|
||||
rajoutés dans le DNS, seuls les noms qualifiés le sont. Deux clients DHCP
|
||||
avec le même nom peuvent tous les deux garder le nom, pour peu que la partie
|
||||
relative au domaine soit différente (c-à-d que les noms pleinements qualifiés
|
||||
diffèrent). Pour d'assurer que tous les noms ont une partie domaine, il doit-y
|
||||
relative au domaine soit différente (c-à-d que les noms pleinement qualifiés
|
||||
diffèrent). Pour s'assurer que tous les noms ont une partie domaine, il doit y
|
||||
avoir au moins un
|
||||
.B --domain
|
||||
sans gamme d'adresses de spécifié lorsque l'option
|
||||
@@ -1729,7 +1743,7 @@ Windows de la mise à jour de serveurs Active Directory. Voir la RFC 4702 pour
|
||||
plus de détails.
|
||||
.TP
|
||||
.B --enable-ra
|
||||
Active la fonctionalité d'annonces routeurs IPv6 ("IPv6 Router Advertisement").
|
||||
Active la fonctionnalité d'annonces routeurs IPv6 ("IPv6 Router Advertisement").
|
||||
DHCPv6 ne gère pas la configuration complète du réseau de la même façon que
|
||||
DHCPv4. La découverte de routeurs et la découverte (éventuelle) de préfixes pour
|
||||
la création autonome d'adresse sont gérées par un protocole différent.
|
||||
@@ -1741,7 +1755,7 @@ dhcp-range et, par défaut, fournir comme valeur de routeur et de DNS récursif
|
||||
la valeur d'adresse link-local appropriée parmi celles de la machine sur
|
||||
laquelle tourne dnsmasq.
|
||||
Par défaut, les bits "managed address" sont positionnés, et le bit "use SLAAC"
|
||||
("utiliser SLAAC") est réinitialisé. Cela peut-être changé pour des
|
||||
("utiliser SLAAC") est réinitialisé. Cela peut être changé pour des
|
||||
sous-réseaux donnés par le biais du mot clef de mode décris dans
|
||||
.B --dhcp-range.
|
||||
Les paramètres DNS du RFC6106 sont inclus dans les annonces. Par défaut,
|
||||
@@ -1750,27 +1764,27 @@ dnsmasq est spécifiée comme DNS récursif. Si elles sont fournies, les
|
||||
options dns-server et domain-search sont utilisées respectivement pour RDNSS et
|
||||
DNSSL.
|
||||
.TP
|
||||
.B --ra-param=<interface>,[high|low],[[<intervalle d'annonce routeur>],<durée de vie route>]
|
||||
.B --ra-param=<interface>,[mtu:<valeur>|<interface>|off,][high,|low,]<intervalle d'annonce routeur>[,<durée de vie route>]
|
||||
Configure pour une interface donnée des valeurs pour les annonces routeurs
|
||||
différentes des valeurs par défaut. La valeur par défaut du champ priorité
|
||||
pour le routeur peut-être changée de "medium" (moyen) à "high" (haute) ou
|
||||
pour le routeur peut être changée de "medium" (moyen) à "high" (haute) ou
|
||||
"low" (basse). Par exemple :
|
||||
.B --ra-param=eth0,high.
|
||||
Un intervalle (en secondes) entre les annonces routeur peut-être fourni par :
|
||||
.B --ra-param=eth0,high,0.
|
||||
Un intervalle (en secondes) entre les annonces routeur peut être fourni par :
|
||||
.B --ra-param=eth0,60.
|
||||
La durée de vie de la route peut-être changée ou mise à zéro, auquel cas
|
||||
La durée de vie de la route peut être changée ou mise à zéro, auquel cas
|
||||
le routeur peut annoncer les préfixes mais pas de route :
|
||||
.B --ra-parm=eth0,0,0
|
||||
(une valeur de zéro pour l'intervalle signifie qu'il garde la valeur par défaut).
|
||||
Ces trois paramètres peuvent-être configurés en une fois :
|
||||
.B --ra-param=low,60,1200
|
||||
Ces quatre paramètres peuvent être configurés en une fois :
|
||||
.B --ra-param=eth0,mtu:1280,low,60,1200
|
||||
La valeur pour l'interface peut inclure un caractère joker.
|
||||
.TP
|
||||
.B --enable-tftp[=<interface>[,<interface>]]
|
||||
Active la fonction serveur TFTP. Celui-ci est de manière délibérée limité aux
|
||||
fonctions nécessaires au démarrage par le réseau ("net-boot") d'un client. Seul
|
||||
un accès en lecture est possible; les extensions tsize et blksize sont supportées
|
||||
(tsize est seulement supporté en mode octet). Sans argument optionel, le service
|
||||
(tsize est seulement supportée en mode octet). Sans argument optionnel, le service
|
||||
TFTP est fourni sur les mêmes interfaces que le service DHCP. Si une liste
|
||||
d'interfaces est fournie, cela définit les interfaces sur lesquelles le
|
||||
service TFTP sera activé.
|
||||
@@ -1841,9 +1855,9 @@ Un serveur TFTP écoute sur le port prédéfini 69 ("well-known port") pour
|
||||
l'initiation de la connexion, mais utilise également un port dynamiquement
|
||||
alloué pour chaque connexion. Normalement, ces ports sont alloués par
|
||||
le système d'exploitation, mais cette option permet de spécifier une gamme
|
||||
de ports à utiliser pour les transferts TFTP. Cela peut-être utile si
|
||||
de ports à utiliser pour les transferts TFTP. Cela peut être utile si
|
||||
TFTP doit traverser un dispositif garde-barrière ("firewall"). La valeur
|
||||
de début pour la plage de port ne peut-être inférieure à 1025 sauf si
|
||||
de début pour la plage de port ne peut être inférieure à 1025 sauf si
|
||||
dnsmasq tourne en temps que super-utilisateur ("root"). Le nombre de
|
||||
connexions TFTP concurrentes est limitée par la taille de la gamme de
|
||||
ports ainsi spécifiée.
|
||||
@@ -1853,8 +1867,8 @@ Un serveur TFTP écoute sur un numéro de port bien connu (69) pour l'initiation
|
||||
de la connexion, et alloue dynamiquement un port pour chaque connexion. Ces
|
||||
numéros de ports sont en principe alloués par le système d'exploitation, mais
|
||||
cette option permet de spécifier une gamme de ports à utiliser pour les
|
||||
transferts TFTP. Cela peut-être utile lorsque ceux-ci doivent traverser un
|
||||
dispositif garde-barrière ("firewall"). Le début de la plage ne peut-être
|
||||
transferts TFTP. Cela peut être utile lorsque ceux-ci doivent traverser un
|
||||
dispositif garde-barrière ("firewall"). Le début de la plage ne peut être
|
||||
inférieur à 1024 à moins que Dnsmasq ne fonctionne en temps que
|
||||
super-utilisateur ("root"). Le nombre maximal de connexions TFTP concurrentes
|
||||
est limitée par la taille de la plage de ports ainsi définie.
|
||||
@@ -1889,7 +1903,7 @@ par "--". Les lignes commençant par # sont des commentaires et sont ignorées.
|
||||
Pour les options qui ne peuvent-être spécifiées qu'une seule fois, celle du
|
||||
fichier de configuration prends le pas sur celle fournie en ligne de commande.
|
||||
Il est possible d'utiliser des guillemets afin d'éviter que les ",",":","." et
|
||||
"#" ne soit interprêtés, et il est possible d'utiliser les séquences
|
||||
"#" ne soient interprétés, et il est possible d'utiliser les séquences
|
||||
d'échappement suivantes : \\\\ \\" \\t \\e \\b \\r et \\n. Elles correspondent
|
||||
respectivement à la barre oblique descendante ("anti-slash"), guillemets doubles,
|
||||
tabulation, caractère d'échappement ("escape"), suppression ("backspace"), retour ("return") et
|
||||
@@ -1934,8 +1948,8 @@ traces dans un fichier (voir
|
||||
.B --log-facility
|
||||
), alors
|
||||
.B Dnsmasq
|
||||
ferme et re-rouvre le fichier de traces. Il faut noter que pendant cette
|
||||
opération Dnsmasq ne s'exécute pas en temps que "root". Lorsqu'il créé un
|
||||
ferme et rouvre le fichier de traces. Il faut noter que pendant cette
|
||||
opération Dnsmasq ne s'exécute pas en tant que "root". Lorsqu'il créé un
|
||||
fichier de traces pour la première fois, Dnsmasq change le propriétaire du
|
||||
fichier afin de le faire appartenir à l'utilisateur non "root" sous lequel
|
||||
Dnsmasq s'exécute. Le logiciel de rotation de fichiers de trace logrotate doit
|
||||
@@ -1977,7 +1991,7 @@ qu'une connexion PPP ne soit établie. Dans ce cas, Dnsmasq vérifie régulière
|
||||
pour voir si un fichier
|
||||
.I /etc/resolv.conf
|
||||
est créé. Dnsmasq peut être configuré pour lire plus d'un fichier resolv.conf.
|
||||
Cela est utile sur un ordinateur portable où PPP et DHCP peuvent-être utilisés :
|
||||
Cela est utile sur un ordinateur portable où PPP et DHCP peuvent être utilisés :
|
||||
Dnsmasq peut alors être configuré pour lire à la fois
|
||||
.I /etc/ppp/resolv.conf
|
||||
et
|
||||
@@ -2001,7 +2015,7 @@ ou alors en mettant leurs adresses dans un autre fichier, par exemple
|
||||
.I /etc/resolv.dnsmasq
|
||||
et en lançant Dnsmasq avec l'option
|
||||
.B \-r /etc/resolv.dnsmasq.
|
||||
Cette deuxième technique permet la mise-à-jour dynamique des addresses de
|
||||
Cette deuxième technique permet la mise-à-jour dynamique des adresses de
|
||||
serveurs DNS amont par le biais de PPP ou DHCP.
|
||||
.PP
|
||||
Les adresses dans /etc/hosts prennent le dessus sur celles fournies par le
|
||||
@@ -2061,10 +2075,10 @@ et pour affecter l'option envoyée, sur la base de la plage sélectionnée.
|
||||
|
||||
Ce système a évolué d'un système plus ancien et aux possibilités plus limitées,
|
||||
et pour des raisons de compatibilité "net:" peut être utilisé à la place de
|
||||
"tag:" et "set:" peut-être omis (à l'exception de
|
||||
"tag:" et "set:" peut être omis (à l'exception de
|
||||
.B dhcp-host,
|
||||
où "net:" peut-être utilisé à la place de "set:"). Pour les mêmes raisons, '#'
|
||||
peut-être utilisé à la place de '!' pour indiquer la négation.
|
||||
où "net:" peut être utilisé à la place de "set:"). Pour les mêmes raisons, '#'
|
||||
peut être utilisé à la place de '!' pour indiquer la négation.
|
||||
.PP
|
||||
Le serveur DHCP intégré dans Dnsmasq fonctionne également en temps que serveur
|
||||
BOOTP, pour peu que l'adresse MAC et l'adresse IP des clients soient fournies,
|
||||
@@ -2091,7 +2105,7 @@ scénarios de complexité croissante. Le pré-requis pour chacun de ces scénari
|
||||
est l'existence d'une adresse IP globalement disponible, d'un enregistrement de
|
||||
type A ou AAAA pointant vers cette adresse, ainsi que d'un serveur DNS externe
|
||||
capable d'effectuer la délégation de la zone en question. Pour la première
|
||||
partie de ces explications, nous allons appeller serveur.exemple.com
|
||||
partie de ces explications, nous allons appeler serveur.exemple.com
|
||||
l'enregistrement A (ou AAAA) de l'adresse globalement accessible, et
|
||||
notre.zone.com la zone pour laquelle dnsmasq fait autorité.
|
||||
|
||||
@@ -2132,11 +2146,11 @@ notre.zone.com NS our.zone.com
|
||||
.fi
|
||||
|
||||
L'enregistrement A pour notre.zone.com est dorénavant un enregistrement "colle"
|
||||
qui résoud le problème de poule et d'oeuf consistant à trouver l'adresse IP
|
||||
qui résout le problème de poule et d'oeuf consistant à trouver l'adresse IP
|
||||
du serveur de nom pour notre.zone.com lorsque l'enregistrement se trouve dans
|
||||
la zone en question. Il s'agit du seul rôle de cet enregistrement : comme dnsmasq
|
||||
fait désormais autorité pour notre.zone.com, il doit également fournir cet
|
||||
enregistrement. Si l'adresse externe est statique, cela peut-être réalisé par
|
||||
enregistrement. Si l'adresse externe est statique, cela peut être réalisé par
|
||||
le biais d'une entrée dans
|
||||
.B /etc/hosts
|
||||
ou via un
|
||||
@@ -2186,9 +2200,9 @@ spécifiques, vous pouvez le faire via :
|
||||
.fi
|
||||
|
||||
Dnsmasq joue le rôle de serveur faisant autorité pour les domaines in-addr.arpa
|
||||
et ipv6.arpa associés aux sous-réseaux définis dans la déclaration de zone
|
||||
et ip6.arpa associés aux sous-réseaux définis dans la déclaration de zone
|
||||
auth-zone, ce qui fait que les requêtes DNS inversées (de l'adresse vers
|
||||
le nom) peuvent-simplement être configurées avec un enregistrement NS
|
||||
le nom) peuvent simplement être configurées avec un enregistrement NS
|
||||
adéquat. Par exemple, comme nous définissons plus haut les adresses
|
||||
1.2.3.0/24 :
|
||||
.nf
|
||||
@@ -2237,7 +2251,7 @@ celui fourni par
|
||||
.B --domain.
|
||||
Si l'option
|
||||
.B --dhcp-fqdn
|
||||
est fournie, alors les noms pleinemenet qualifiés associés aux baux DHCP
|
||||
est fournie, alors les noms pleinement qualifiés associés aux baux DHCP
|
||||
sont utilisés, dès lors qu'ils correspondent au nom de domaine associé
|
||||
à la zone.
|
||||
|
||||
@@ -2276,7 +2290,7 @@ Dnsmasq est capable de gérer le DNS et DHCP pour au moins un millier de clients
|
||||
Pour cela, la durée des bail ne doit pas être très courte (moins d'une heure).
|
||||
La valeur de
|
||||
.B --dns-forward-max
|
||||
peut-être augmentée : commencer par la rendre égale au nombre de clients et
|
||||
peut être augmentée : commencer par la rendre égale au nombre de clients et
|
||||
l'augmenter si le DNS semble lent. Noter que la performance du DNS dépends
|
||||
également de la performance des serveurs amonts. La taille du cache DNS peut-
|
||||
être augmentée : la limite en dur est de 10000 entrées et la valeur par défaut
|
||||
@@ -2300,7 +2314,7 @@ Il est possible d'utiliser Dnsmasq pour bloquer la publicité sur la toile
|
||||
en associant des serveurs de publicité bien connus à l'adresse 127.0.0.1 ou
|
||||
0.0.0.0 par le biais du fichier
|
||||
.B /etc/hosts
|
||||
ou d'un fichier d'hôte additionnel. Cette liste peut-être très longue, Dnsmasq
|
||||
ou d'un fichier d'hôte additionnel. Cette liste peut être très longue, Dnsmasq
|
||||
ayant été testé avec succès avec un million de noms. Cette taille de fichier
|
||||
nécessite un processeur à 1 Ghz et environ 60 Mo de RAM.
|
||||
|
||||
|
||||
1514
po/pt_BR.po
1514
po/pt_BR.po
File diff suppressed because it is too large
Load Diff
10
setup.html
10
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
|
||||
|
||||
247
src/arp.c
Normal file
247
src/arp.c
Normal file
@@ -0,0 +1,247 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2018 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];
|
||||
struct 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, char *addrp, char *mac, size_t maclen, void *parmv)
|
||||
{
|
||||
struct arp_record *arp;
|
||||
|
||||
(void)parmv;
|
||||
|
||||
if (maclen > DHCP_CHADDR_MAX)
|
||||
return 1;
|
||||
|
||||
#ifndef HAVE_IPV6
|
||||
if (family != AF_INET)
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
/* 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.addr.addr4.s_addr != ((struct in_addr *)addrp)->s_addr)
|
||||
continue;
|
||||
}
|
||||
#ifdef HAVE_IPV6
|
||||
else
|
||||
{
|
||||
if (!IN6_ARE_ADDR_EQUAL(&arp->addr.addr.addr6, (struct in6_addr *)addrp))
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
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.addr.addr4.s_addr = ((struct in_addr *)addrp)->s_addr;
|
||||
#ifdef HAVE_IPV6
|
||||
else
|
||||
memcpy(&arp->addr.addr.addr6, addrp, IN6ADDRSZ);
|
||||
#endif
|
||||
}
|
||||
|
||||
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.addr.addr4.s_addr != addr->in.sin_addr.s_addr)
|
||||
continue;
|
||||
|
||||
#ifdef HAVE_IPV6
|
||||
if (arp->family == AF_INET6 &&
|
||||
!IN6_ARE_ADDR_EQUAL(&arp->addr.addr.addr6, &addr->in6.sin6_addr))
|
||||
continue;
|
||||
#endif
|
||||
|
||||
/* 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, 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.addr.addr4.s_addr = addr->in.sin_addr.s_addr;
|
||||
#ifdef HAVE_IPV6
|
||||
else
|
||||
memcpy(&arp->addr.addr.addr6, &addr->in6.sin6_addr, IN6ADDRSZ);
|
||||
#endif
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
244
src/auth.c
244
src/auth.c
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2014 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2018 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
|
||||
@@ -18,36 +18,53 @@
|
||||
|
||||
#ifdef HAVE_AUTH
|
||||
|
||||
static struct addrlist *find_addrlist(struct addrlist *list, int flag, struct all_addr *addr_u)
|
||||
{
|
||||
do {
|
||||
if (!(list->flags & ADDRLIST_IPV6))
|
||||
{
|
||||
struct in_addr netmask, addr = addr_u->addr.addr4;
|
||||
|
||||
if (!(flag & F_IPV4))
|
||||
continue;
|
||||
|
||||
netmask.s_addr = htonl(~(in_addr_t)0 << (32 - list->prefixlen));
|
||||
|
||||
if (is_same_net(addr, list->addr.addr.addr4, netmask))
|
||||
return list;
|
||||
}
|
||||
#ifdef HAVE_IPV6
|
||||
else if (is_same_net6(&(addr_u->addr.addr6), &list->addr.addr.addr6, list->prefixlen))
|
||||
return list;
|
||||
#endif
|
||||
|
||||
} while ((list = list->next));
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct addrlist *find_subnet(struct auth_zone *zone, int flag, struct all_addr *addr_u)
|
||||
{
|
||||
struct addrlist *subnet;
|
||||
if (!zone->subnet)
|
||||
return NULL;
|
||||
|
||||
return find_addrlist(zone->subnet, flag, addr_u);
|
||||
}
|
||||
|
||||
for (subnet = zone->subnet; subnet; subnet = subnet->next)
|
||||
{
|
||||
if (!(subnet->flags & ADDRLIST_IPV6))
|
||||
{
|
||||
struct in_addr netmask, addr = addr_u->addr.addr4;
|
||||
|
||||
if (!(flag & F_IPV4))
|
||||
continue;
|
||||
|
||||
netmask.s_addr = htonl(~((1 << (32 - subnet->prefixlen)) - 1));
|
||||
|
||||
if (is_same_net(addr, subnet->addr.addr.addr4, netmask))
|
||||
return subnet;
|
||||
}
|
||||
#ifdef HAVE_IPV6
|
||||
else if (is_same_net6(&(addr_u->addr.addr6), &subnet->addr.addr.addr6, subnet->prefixlen))
|
||||
return subnet;
|
||||
#endif
|
||||
|
||||
}
|
||||
return NULL;
|
||||
static struct addrlist *find_exclude(struct auth_zone *zone, int flag, struct 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, struct all_addr *addr_u)
|
||||
{
|
||||
/* No zones specified, no filter */
|
||||
if (find_exclude(zone, flag, addr_u))
|
||||
return 0;
|
||||
|
||||
/* No subnets specified, no filter */
|
||||
if (!zone->subnet)
|
||||
return 1;
|
||||
|
||||
@@ -81,7 +98,8 @@ int in_zone(struct auth_zone *zone, char *name, char **cut)
|
||||
}
|
||||
|
||||
|
||||
size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t now, union mysockaddr *peer_addr, int local_query)
|
||||
size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t now, union mysockaddr *peer_addr,
|
||||
int local_query, int do_bit, int have_pseudoheader)
|
||||
{
|
||||
char *name = daemon->namebuff;
|
||||
unsigned char *p, *ansp;
|
||||
@@ -98,7 +116,8 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
||||
struct interface_name *intr;
|
||||
struct naptr *na;
|
||||
struct all_addr addr;
|
||||
struct cname *a;
|
||||
struct cname *a, *candidate;
|
||||
unsigned int wclen;
|
||||
|
||||
if (ntohs(header->qdcount) == 0 || OPCODE(header) != QUERY )
|
||||
return 0;
|
||||
@@ -114,6 +133,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
||||
{
|
||||
unsigned short flag = 0;
|
||||
int found = 0;
|
||||
int cname_wildcard = 0;
|
||||
|
||||
/* save pointer to name for copying into answers */
|
||||
nameoffset = p - (unsigned char *)header;
|
||||
@@ -131,24 +151,27 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
||||
continue;
|
||||
}
|
||||
|
||||
if (qtype == T_PTR)
|
||||
if ((qtype == T_PTR || qtype == T_SOA || qtype == T_NS) &&
|
||||
(flag = in_arpa_name_2_addr(name, &addr)) &&
|
||||
!local_query)
|
||||
{
|
||||
if (!(flag = in_arpa_name_2_addr(name, &addr)))
|
||||
continue;
|
||||
|
||||
if (!local_query)
|
||||
for (zone = daemon->auth_zones; zone; zone = zone->next)
|
||||
if ((subnet = find_subnet(zone, flag, &addr)))
|
||||
break;
|
||||
|
||||
if (!zone)
|
||||
{
|
||||
for (zone = daemon->auth_zones; zone; zone = zone->next)
|
||||
if ((subnet = find_subnet(zone, flag, &addr)))
|
||||
break;
|
||||
|
||||
if (!zone)
|
||||
{
|
||||
auth = 0;
|
||||
continue;
|
||||
}
|
||||
auth = 0;
|
||||
continue;
|
||||
}
|
||||
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)
|
||||
@@ -186,7 +209,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
||||
|
||||
if (intr)
|
||||
{
|
||||
if (in_zone(zone, intr->name, NULL))
|
||||
if (local_query || in_zone(zone, intr->name, NULL))
|
||||
{
|
||||
found = 1;
|
||||
log_query(flag | F_REVERSE | F_CONFIG, intr->name, &addr, NULL);
|
||||
@@ -208,8 +231,11 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
||||
*p = 0; /* must be bare name */
|
||||
|
||||
/* add external domain */
|
||||
strcat(name, ".");
|
||||
strcat(name, zone->domain);
|
||||
if (zone)
|
||||
{
|
||||
strcat(name, ".");
|
||||
strcat(name, zone->domain);
|
||||
}
|
||||
log_query(flag | F_DHCP | F_REVERSE, name, &addr, record_source(crecp->uid));
|
||||
found = 1;
|
||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
||||
@@ -217,7 +243,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
||||
T_PTR, C_IN, "d", name))
|
||||
anscount++;
|
||||
}
|
||||
else if (crecp->flags & (F_DHCP | F_HOSTS) && in_zone(zone, name, NULL))
|
||||
else if (crecp->flags & (F_DHCP | F_HOSTS) && (local_query || in_zone(zone, name, NULL)))
|
||||
{
|
||||
log_query(crecp->flags & ~F_FORWARD, name, &addr, record_source(crecp->uid));
|
||||
found = 1;
|
||||
@@ -231,21 +257,29 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
||||
|
||||
} while ((crecp = cache_find_by_addr(crecp, &addr, now, flag)));
|
||||
|
||||
if (!found)
|
||||
log_query(flag | F_NEG | F_NXDOMAIN | F_REVERSE | F_AUTH, NULL, &addr, NULL);
|
||||
if (found)
|
||||
nxdomain = 0;
|
||||
else
|
||||
log_query(flag | F_NEG | F_NXDOMAIN | F_REVERSE | (auth ? F_AUTH : 0), NULL, &addr, NULL);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
cname_restart:
|
||||
for (zone = daemon->auth_zones; zone; zone = zone->next)
|
||||
if (in_zone(zone, name, &cut))
|
||||
break;
|
||||
|
||||
if (!zone)
|
||||
if (found)
|
||||
/* NS and SOA .arpa requests have set found above. */
|
||||
cut = NULL;
|
||||
else
|
||||
{
|
||||
auth = 0;
|
||||
continue;
|
||||
for (zone = daemon->auth_zones; zone; zone = zone->next)
|
||||
if (in_zone(zone, name, &cut))
|
||||
break;
|
||||
|
||||
if (!zone)
|
||||
{
|
||||
auth = 0;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
for (rec = daemon->mxnames; rec; rec = rec->next)
|
||||
@@ -361,6 +395,10 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
||||
if (((addrlist->flags & ADDRLIST_IPV6) ? T_AAAA : T_A) == qtype &&
|
||||
(local_query || filter_zone(zone, flag, &addrlist->addr)))
|
||||
{
|
||||
#ifdef HAVE_IPV6
|
||||
if (addrlist->flags & ADDRLIST_REVONLY)
|
||||
continue;
|
||||
#endif
|
||||
found = 1;
|
||||
log_query(F_FORWARD | F_CONFIG | flag, name, &addrlist->addr, NULL);
|
||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
||||
@@ -370,25 +408,6 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
||||
}
|
||||
}
|
||||
|
||||
for (a = daemon->cnames; a; a = a->next)
|
||||
if (hostname_isequal(name, a->alias) )
|
||||
{
|
||||
log_query(F_CONFIG | F_CNAME, name, NULL, NULL);
|
||||
strcpy(name, a->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;
|
||||
}
|
||||
|
||||
if (!cut)
|
||||
{
|
||||
nxdomain = 0;
|
||||
@@ -407,15 +426,19 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
||||
peer_addr->in.sin_port = 0;
|
||||
#ifdef HAVE_IPV6
|
||||
else
|
||||
peer_addr->in6.sin6_port = 0;
|
||||
{
|
||||
peer_addr->in6.sin6_port = 0;
|
||||
peer_addr->in6.sin6_scope_id = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (peers = daemon->auth_peers; peers; peers = peers->next)
|
||||
if (sockaddr_isequal(peer_addr, &peers->addr))
|
||||
break;
|
||||
|
||||
/* Refuse all AXFR unless --auth-sec-servers is set */
|
||||
if ((!peers && daemon->auth_peers) || !daemon->secondary_forward_server)
|
||||
/* 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);
|
||||
@@ -491,8 +514,62 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
||||
} while ((crecp = cache_find_by_name(crecp, name, now, F_IPV4 | F_IPV6)));
|
||||
}
|
||||
|
||||
if (!found)
|
||||
log_query(flag | F_NEG | (nxdomain ? F_NXDOMAIN : 0) | F_FORWARD | F_AUTH, name, NULL, NULL);
|
||||
/* 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(F_CONFIG | F_CNAME, name, NULL, NULL);
|
||||
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;
|
||||
}
|
||||
|
||||
log_query(flag | F_NEG | (nxdomain ? F_NXDOMAIN : 0) | F_FORWARD | F_AUTH, name, NULL, NULL);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -516,12 +593,12 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
||||
char *p = name;
|
||||
|
||||
if (subnet->prefixlen >= 24)
|
||||
p += sprintf(p, "%d.", a & 0xff);
|
||||
p += sprintf(p, "%u.", a & 0xff);
|
||||
a = a >> 8;
|
||||
if (subnet->prefixlen >= 16 )
|
||||
p += sprintf(p, "%d.", a & 0xff);
|
||||
p += sprintf(p, "%u.", a & 0xff);
|
||||
a = a >> 8;
|
||||
p += sprintf(p, "%d.in-addr.arpa", a & 0xff);
|
||||
p += sprintf(p, "%u.in-addr.arpa", a & 0xff);
|
||||
|
||||
}
|
||||
#ifdef HAVE_IPV6
|
||||
@@ -784,7 +861,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
||||
header->hb4 &= ~HB4_RA;
|
||||
}
|
||||
|
||||
/* authoritive */
|
||||
/* authoritative */
|
||||
if (auth)
|
||||
header->hb3 |= HB3_AA;
|
||||
|
||||
@@ -799,6 +876,11 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
||||
header->ancount = htons(anscount);
|
||||
header->nscount = htons(authcount);
|
||||
header->arcount = htons(0);
|
||||
|
||||
/* Advertise our packet size limit in our reply */
|
||||
if (have_pseudoheader)
|
||||
return add_pseudoheader(header, ansp - (unsigned char *)header, (unsigned char *)limit, daemon->edns_pktsz, 0, NULL, 0, do_bit, 0);
|
||||
|
||||
return ansp - (unsigned char *)header;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2014 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2018 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
|
||||
@@ -46,14 +46,19 @@ void blockdata_init(void)
|
||||
blockdata_alloced = 0;
|
||||
blockdata_count = 0;
|
||||
blockdata_hwm = 0;
|
||||
|
||||
blockdata_expand((daemon->cachesize * 100) / sizeof(struct blockdata));
|
||||
|
||||
/* Note that daemon->cachesize is enforced to have non-zero size if OPT_DNSSEC_VALID is set */
|
||||
if (option_bool(OPT_DNSSEC_VALID))
|
||||
blockdata_expand(daemon->cachesize);
|
||||
}
|
||||
|
||||
void blockdata_report(void)
|
||||
{
|
||||
my_syslog(LOG_INFO, _("DNSSEC memory in use %u, max %u, allocated %u"),
|
||||
blockdata_count * sizeof(struct blockdata), blockdata_hwm * sizeof(struct blockdata), blockdata_alloced * sizeof(struct blockdata));
|
||||
if (option_bool(OPT_DNSSEC_VALID))
|
||||
my_syslog(LOG_INFO, _("DNSSEC memory in use %u, max %u, allocated %u"),
|
||||
blockdata_count * sizeof(struct blockdata),
|
||||
blockdata_hwm * sizeof(struct blockdata),
|
||||
blockdata_alloced * sizeof(struct blockdata));
|
||||
}
|
||||
|
||||
struct blockdata *blockdata_alloc(char *data, size_t len)
|
||||
@@ -95,6 +100,7 @@ struct blockdata *blockdata_alloc(char *data, size_t len)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void blockdata_free(struct blockdata *blocks)
|
||||
{
|
||||
struct blockdata *tmp;
|
||||
|
||||
18
src/bpf.c
18
src/bpf.c
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2014 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2018 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
|
||||
@@ -20,7 +20,9 @@
|
||||
#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>
|
||||
@@ -103,7 +105,7 @@ int arp_enumerate(void *parm, int (*callback)())
|
||||
int iface_enumerate(int family, void *parm, int (*callback)())
|
||||
{
|
||||
struct ifaddrs *head, *addrs;
|
||||
int errsav, fd = -1, ret = 0;
|
||||
int errsave, fd = -1, ret = 0;
|
||||
|
||||
if (family == AF_UNSPEC)
|
||||
#if defined(HAVE_BSD_NETWORK) && !defined(__APPLE__)
|
||||
@@ -235,11 +237,11 @@ int iface_enumerate(int family, void *parm, int (*callback)())
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
errsav = errno;
|
||||
errsave = errno;
|
||||
freeifaddrs(head);
|
||||
if (fd != -1)
|
||||
close(fd);
|
||||
errno = errsav;
|
||||
errno = errsave;
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -359,7 +361,7 @@ void send_via_bpf(struct dhcp_packet *mess, size_t len,
|
||||
iov[3].iov_base = mess;
|
||||
iov[3].iov_len = len;
|
||||
|
||||
while (writev(daemon->dhcp_raw_fd, iov, 4) == -1 && retry_send());
|
||||
while (retry_send(writev(daemon->dhcp_raw_fd, iov, 4)));
|
||||
}
|
||||
|
||||
#endif /* defined(HAVE_BSD_NETWORK) && defined(HAVE_DHCP) */
|
||||
@@ -376,7 +378,7 @@ void route_init(void)
|
||||
die(_("cannot create PF_ROUTE socket: %s"), NULL, EC_BADNET);
|
||||
}
|
||||
|
||||
void route_sock(time_t now)
|
||||
void route_sock(void)
|
||||
{
|
||||
struct if_msghdr *msg;
|
||||
int rc = recv(daemon->routefd, daemon->packet, daemon->packet_buff_sz, 0);
|
||||
@@ -401,7 +403,7 @@ void route_sock(time_t now)
|
||||
else if (msg->ifm_type == RTM_NEWADDR)
|
||||
{
|
||||
del_family = 0;
|
||||
newaddress(now);
|
||||
queue_event(EVENT_NEWADDR);
|
||||
}
|
||||
else if (msg->ifm_type == RTM_DELADDR)
|
||||
{
|
||||
@@ -439,7 +441,7 @@ void route_sock(time_t now)
|
||||
of += sizeof(long) - (diff & (sizeof(long) - 1));
|
||||
}
|
||||
|
||||
newaddress(now);
|
||||
queue_event(EVENT_NEWADDR);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
673
src/cache.c
673
src/cache.c
File diff suppressed because it is too large
Load Diff
112
src/config.h
112
src/config.h
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2014 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2018 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
|
||||
@@ -17,20 +17,29 @@
|
||||
#define FTABSIZ 150 /* max number of outstanding requests (default) */
|
||||
#define MAX_PROCS 20 /* max no children for TCP requests */
|
||||
#define CHILD_LIFETIME 150 /* secs 'till terminated (RFC1035 suggests > 120s) */
|
||||
#define TCP_MAX_QUERIES 100 /* Maximum number of queries per incoming TCP connection */
|
||||
#define TCP_BACKLOG 32 /* kernel backlog limit for TCP connections */
|
||||
#define EDNS_PKTSZ 4096 /* default max EDNS.0 UDP packet from RFC5625 */
|
||||
#define KEYBLOCK_LEN 35 /* choose to mininise fragmentation when storing DNSSEC keys */
|
||||
#define SAFE_PKTSZ 1280 /* "go anywhere" UDP packet size */
|
||||
#define KEYBLOCK_LEN 40 /* choose to minimise fragmentation when storing DNSSEC keys */
|
||||
#define DNSSEC_WORK 50 /* Max number of queries to validate one question */
|
||||
#define TIMEOUT 10 /* drop UDP queries after TIMEOUT seconds */
|
||||
#define FORWARD_TEST 50 /* try all servers every 50 queries */
|
||||
#define FORWARD_TIME 20 /* or 20 seconds */
|
||||
#define UDP_TEST_TIME 60 /* How often to reset our idea of max packet size. */
|
||||
#define SERVERS_LOGGED 30 /* Only log this many servers when logging state */
|
||||
#define LOCALS_LOGGED 8 /* Only log this many local addresses when logging state */
|
||||
#define RANDOM_SOCKS 64 /* max simultaneous random ports */
|
||||
#define LEASE_RETRY 60 /* on error, retry writing leasefile after LEASE_RETRY seconds */
|
||||
#define CACHESIZ 150 /* default cache size */
|
||||
#define TTL_FLOOR_LIMIT 3600 /* don't allow --min-cache-ttl to raise TTL above this under any circumstances */
|
||||
#define MAXLEASES 1000 /* maximum number of DHCP leases */
|
||||
#define PING_WAIT 3 /* wait for ping address-in-use test */
|
||||
#define PING_CACHE_TIME 30 /* Ping test assumed to be valid this long. */
|
||||
#define DECLINE_BACKOFF 600 /* disable DECLINEd static addresses for this long */
|
||||
#define DHCP_PACKET_MAX 16384 /* hard limit on DHCP packet size */
|
||||
#define SMALLDNAME 40 /* most domain names are smaller than this */
|
||||
#define SMALLDNAME 50 /* most domain names are smaller than this */
|
||||
#define CNAME_CHAIN 10 /* chains longer than this atr dropped for loop protection */
|
||||
#define HOSTSFILE "/etc/hosts"
|
||||
#define ETHERSFILE "/etc/ethers"
|
||||
#define DEFLEASE 3600 /* default lease time, 1 hour */
|
||||
@@ -45,6 +54,8 @@
|
||||
#define SOA_REFRESH 1200 /* SOA refresh default */
|
||||
#define SOA_RETRY 180 /* SOA retry default */
|
||||
#define SOA_EXPIRY 1209600 /* SOA expiry default */
|
||||
#define LOOP_TEST_DOMAIN "test" /* domain for loop testing, "test" is reserved by RFC 2606 and won't therefore clash */
|
||||
#define LOOP_TEST_TYPE T_TXT
|
||||
|
||||
/* compile-time options: uncomment below to enable or do eg.
|
||||
make COPTS=-DHAVE_BROKEN_RTC
|
||||
@@ -84,13 +95,13 @@ HAVE_DBUS
|
||||
servers via DBus.
|
||||
|
||||
HAVE_IDN
|
||||
define this if you want international domain name support.
|
||||
NOTE: for backwards compatibility, IDN support is automatically
|
||||
included when internationalisation support is built, using the
|
||||
*-i18n makefile targets, even if HAVE_IDN is not explicitly set.
|
||||
define this if you want international domain name 2003 support.
|
||||
|
||||
HAVE_LIBIDN2
|
||||
define this if you want international domain name 2008 support.
|
||||
|
||||
HAVE_CONNTRACK
|
||||
define this to include code which propogates conntrack marks from
|
||||
define this to include code which propagates conntrack marks from
|
||||
incoming DNS queries to the corresponding upstream queries. This adds
|
||||
a build-dependency on libnetfilter_conntrack, but the resulting binary will
|
||||
still run happily on a kernel without conntrack support.
|
||||
@@ -103,7 +114,20 @@ HAVE_AUTH
|
||||
define this to include the facility to act as an authoritative DNS
|
||||
server for one or more zones.
|
||||
|
||||
HAVE_DNSSEC
|
||||
include DNSSEC validator.
|
||||
|
||||
HAVE_DUMPFILE
|
||||
include code to dump packets to a libpcap-format file for debugging.
|
||||
|
||||
HAVE_LOOP
|
||||
include functionality to probe for and remove DNS forwarding loops.
|
||||
|
||||
HAVE_INOTIFY
|
||||
use the Linux inotify facility to efficiently re-read configuration files.
|
||||
|
||||
NO_ID
|
||||
Don't report *.bind CHAOS info to clients, forward such requests upstream instead.
|
||||
NO_IPV6
|
||||
NO_TFTP
|
||||
NO_DHCP
|
||||
@@ -111,10 +135,14 @@ NO_DHCP6
|
||||
NO_SCRIPT
|
||||
NO_LARGEFILE
|
||||
NO_AUTH
|
||||
these are avilable to explictly disable compile time options which would
|
||||
NO_DUMPFILE
|
||||
NO_INOTIFY
|
||||
these are available to explicitly disable compile time options which would
|
||||
otherwise be enabled automatically (HAVE_IPV6, >2Gb file sizes) or
|
||||
which are enabled by default in the distributed source tree. Building dnsmasq
|
||||
with something like "make COPTS=-DNO_SCRIPT" will do the trick.
|
||||
NO_GMP
|
||||
Don't use and link against libgmp, Useful if nettle is built with --enable-mini-gmp.
|
||||
|
||||
LEASEFILE
|
||||
CONFFILE
|
||||
@@ -139,6 +167,8 @@ RESOLVFILE
|
||||
#define HAVE_SCRIPT
|
||||
#define HAVE_AUTH
|
||||
#define HAVE_IPSET
|
||||
#define HAVE_LOOP
|
||||
#define HAVE_DUMPFILE
|
||||
|
||||
/* Build options which require external libraries.
|
||||
|
||||
@@ -150,6 +180,7 @@ RESOLVFILE
|
||||
/* #define HAVE_LUASCRIPT */
|
||||
/* #define HAVE_DBUS */
|
||||
/* #define HAVE_IDN */
|
||||
/* #define HAVE_LIBIDN2 */
|
||||
/* #define HAVE_CONNTRACK */
|
||||
/* #define HAVE_DNSSEC */
|
||||
|
||||
@@ -206,7 +237,7 @@ HAVE_SOCKADDR_SA_LEN
|
||||
defined if struct sockaddr has sa_len field (*BSD)
|
||||
*/
|
||||
|
||||
/* Must preceed __linux__ since uClinux defines __linux__ too. */
|
||||
/* Must precede __linux__ since uClinux defines __linux__ too. */
|
||||
#if defined(__uClinux__)
|
||||
#define HAVE_LINUX_NETWORK
|
||||
#define HAVE_GETOPT_LONG
|
||||
@@ -244,7 +275,7 @@ HAVE_SOCKADDR_SA_LEN
|
||||
defined(__DragonFly__) || \
|
||||
defined(__FreeBSD_kernel__)
|
||||
#define HAVE_BSD_NETWORK
|
||||
/* Later verions of FreeBSD have getopt_long() */
|
||||
/* Later versions of FreeBSD have getopt_long() */
|
||||
#if defined(optional_argument) && defined(required_argument)
|
||||
# define HAVE_GETOPT_LONG
|
||||
#endif
|
||||
@@ -259,6 +290,7 @@ HAVE_SOCKADDR_SA_LEN
|
||||
/* Select the RFC_3542 version of the IPv6 socket API.
|
||||
Define before netinet6/in6.h is included. */
|
||||
#define __APPLE_USE_RFC_3542
|
||||
#define NO_IPSET
|
||||
|
||||
#elif defined(__NetBSD__)
|
||||
#define HAVE_BSD_NETWORK
|
||||
@@ -314,7 +346,7 @@ HAVE_SOCKADDR_SA_LEN
|
||||
#define HAVE_DHCP
|
||||
#endif
|
||||
|
||||
#if defined(NO_SCRIPT) || !defined(HAVE_DHCP) || defined(NO_FORK)
|
||||
#if defined(NO_SCRIPT) || defined(NO_FORK)
|
||||
#undef HAVE_SCRIPT
|
||||
#undef HAVE_LUASCRIPT
|
||||
#endif
|
||||
@@ -328,12 +360,24 @@ HAVE_SOCKADDR_SA_LEN
|
||||
#undef HAVE_AUTH
|
||||
#endif
|
||||
|
||||
#if defined(NO_IPSET) || !defined(HAVE_LINUX_NETWORK)
|
||||
#if defined(NO_IPSET)
|
||||
#undef HAVE_IPSET
|
||||
#endif
|
||||
|
||||
#ifdef NO_LOOP
|
||||
#undef HAVE_LOOP
|
||||
#endif
|
||||
|
||||
#ifdef NO_DUMPFILE
|
||||
#undef HAVE_DUMPFILE
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_LINUX_NETWORK) && !defined(NO_INOTIFY)
|
||||
#define HAVE_INOTIFY
|
||||
#endif
|
||||
|
||||
/* Define a string indicating which options are in use.
|
||||
DNSMASQP_COMPILE_OPTS is only defined in dnsmasq.c */
|
||||
DNSMASQ_COMPILE_OPTS is only defined in dnsmasq.c */
|
||||
|
||||
#ifdef DNSMASQ_COMPILE_OPTS
|
||||
|
||||
@@ -360,10 +404,14 @@ static char *compile_opts =
|
||||
"no-"
|
||||
#endif
|
||||
"i18n "
|
||||
#if !defined(LOCALEDIR) && !defined(HAVE_IDN)
|
||||
#if defined(HAVE_LIBIDN2)
|
||||
"IDN2 "
|
||||
#else
|
||||
#if !defined(HAVE_IDN)
|
||||
"no-"
|
||||
#endif
|
||||
"IDN "
|
||||
#endif
|
||||
"IDN "
|
||||
#endif
|
||||
#ifndef HAVE_DHCP
|
||||
"no-"
|
||||
#endif
|
||||
@@ -373,14 +421,14 @@ static char *compile_opts =
|
||||
"no-"
|
||||
# endif
|
||||
"DHCPv6 "
|
||||
# if !defined(HAVE_SCRIPT)
|
||||
#endif
|
||||
#if !defined(HAVE_SCRIPT)
|
||||
"no-scripts "
|
||||
# else
|
||||
# if !defined(HAVE_LUASCRIPT)
|
||||
"no-"
|
||||
# endif
|
||||
"Lua "
|
||||
#else
|
||||
# if !defined(HAVE_LUASCRIPT)
|
||||
"no-"
|
||||
# endif
|
||||
"Lua "
|
||||
#endif
|
||||
#ifndef HAVE_TFTP
|
||||
"no-"
|
||||
@@ -401,8 +449,22 @@ static char *compile_opts =
|
||||
#ifndef HAVE_DNSSEC
|
||||
"no-"
|
||||
#endif
|
||||
"DNSSEC";
|
||||
|
||||
"DNSSEC "
|
||||
#ifdef NO_ID
|
||||
"no-ID "
|
||||
#endif
|
||||
#ifndef HAVE_LOOP
|
||||
"no-"
|
||||
#endif
|
||||
"loop-detect "
|
||||
#ifndef HAVE_INOTIFY
|
||||
"no-"
|
||||
#endif
|
||||
"inotify "
|
||||
#ifndef HAVE_DUMPFILE
|
||||
"no-"
|
||||
#endif
|
||||
"dumpfile";
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2014 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2018 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
|
||||
|
||||
460
src/crypto.c
Normal file
460
src/crypto.c
Normal file
@@ -0,0 +1,460 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2018 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_DNSSEC
|
||||
|
||||
#include <nettle/rsa.h>
|
||||
#include <nettle/dsa.h>
|
||||
#include <nettle/ecdsa.h>
|
||||
#include <nettle/ecc-curve.h>
|
||||
#include <nettle/eddsa.h>
|
||||
#include <nettle/nettle-meta.h>
|
||||
#include <nettle/bignum.h>
|
||||
|
||||
/* Implement a "hash-function" to the nettle API, which simply returns
|
||||
the input data, concatenated into a single, statically maintained, buffer.
|
||||
|
||||
Used for the EdDSA sigs, which operate on the whole message, rather
|
||||
than a digest. */
|
||||
|
||||
struct null_hash_digest
|
||||
{
|
||||
uint8_t *buff;
|
||||
size_t len;
|
||||
};
|
||||
|
||||
struct null_hash_ctx
|
||||
{
|
||||
size_t len;
|
||||
};
|
||||
|
||||
static size_t null_hash_buff_sz = 0;
|
||||
static uint8_t *null_hash_buff = NULL;
|
||||
#define BUFF_INCR 128
|
||||
|
||||
static void null_hash_init(void *ctx)
|
||||
{
|
||||
((struct null_hash_ctx *)ctx)->len = 0;
|
||||
}
|
||||
|
||||
static void null_hash_update(void *ctxv, size_t length, const uint8_t *src)
|
||||
{
|
||||
struct null_hash_ctx *ctx = ctxv;
|
||||
size_t new_len = ctx->len + length;
|
||||
|
||||
if (new_len > null_hash_buff_sz)
|
||||
{
|
||||
uint8_t *new;
|
||||
|
||||
if (!(new = whine_malloc(new_len + BUFF_INCR)))
|
||||
return;
|
||||
|
||||
if (null_hash_buff)
|
||||
{
|
||||
if (ctx->len != 0)
|
||||
memcpy(new, null_hash_buff, ctx->len);
|
||||
free(null_hash_buff);
|
||||
}
|
||||
|
||||
null_hash_buff_sz = new_len + BUFF_INCR;
|
||||
null_hash_buff = new;
|
||||
}
|
||||
|
||||
memcpy(null_hash_buff + ctx->len, src, length);
|
||||
ctx->len += length;
|
||||
}
|
||||
|
||||
|
||||
static void null_hash_digest(void *ctx, size_t length, uint8_t *dst)
|
||||
{
|
||||
(void)length;
|
||||
|
||||
((struct null_hash_digest *)dst)->buff = null_hash_buff;
|
||||
((struct null_hash_digest *)dst)->len = ((struct null_hash_ctx *)ctx)->len;
|
||||
}
|
||||
|
||||
static struct nettle_hash null_hash = {
|
||||
"null_hash",
|
||||
sizeof(struct null_hash_ctx),
|
||||
sizeof(struct null_hash_digest),
|
||||
0,
|
||||
(nettle_hash_init_func *) null_hash_init,
|
||||
(nettle_hash_update_func *) null_hash_update,
|
||||
(nettle_hash_digest_func *) null_hash_digest
|
||||
};
|
||||
|
||||
/* Find pointer to correct hash function in nettle library */
|
||||
const struct nettle_hash *hash_find(char *name)
|
||||
{
|
||||
if (!name)
|
||||
return NULL;
|
||||
|
||||
/* We provide a "null" hash which returns the input data as digest. */
|
||||
if (strcmp(null_hash.name, name) == 0)
|
||||
return &null_hash;
|
||||
|
||||
/* libnettle >= 3.4 provides nettle_lookup_hash() which avoids nasty ABI
|
||||
incompatibilities if sizeof(nettle_hashes) changes between library
|
||||
versions. It also #defines nettle_hashes, so use that to tell
|
||||
if we have the new facilities. */
|
||||
|
||||
#ifdef nettle_hashes
|
||||
return nettle_lookup_hash(name);
|
||||
#else
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; nettle_hashes[i]; i++)
|
||||
if (strcmp(nettle_hashes[i]->name, name) == 0)
|
||||
return nettle_hashes[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* expand ctx and digest memory allocations if necessary and init hash function */
|
||||
int hash_init(const struct nettle_hash *hash, void **ctxp, unsigned char **digestp)
|
||||
{
|
||||
static void *ctx = NULL;
|
||||
static unsigned char *digest = NULL;
|
||||
static unsigned int ctx_sz = 0;
|
||||
static unsigned int digest_sz = 0;
|
||||
|
||||
void *new;
|
||||
|
||||
if (ctx_sz < hash->context_size)
|
||||
{
|
||||
if (!(new = whine_malloc(hash->context_size)))
|
||||
return 0;
|
||||
if (ctx)
|
||||
free(ctx);
|
||||
ctx = new;
|
||||
ctx_sz = hash->context_size;
|
||||
}
|
||||
|
||||
if (digest_sz < hash->digest_size)
|
||||
{
|
||||
if (!(new = whine_malloc(hash->digest_size)))
|
||||
return 0;
|
||||
if (digest)
|
||||
free(digest);
|
||||
digest = new;
|
||||
digest_sz = hash->digest_size;
|
||||
}
|
||||
|
||||
*ctxp = ctx;
|
||||
*digestp = digest;
|
||||
|
||||
hash->init(ctx);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int dnsmasq_rsa_verify(struct blockdata *key_data, unsigned int key_len, unsigned char *sig, size_t sig_len,
|
||||
unsigned char *digest, size_t digest_len, int algo)
|
||||
{
|
||||
unsigned char *p;
|
||||
size_t exp_len;
|
||||
|
||||
static struct rsa_public_key *key = NULL;
|
||||
static mpz_t sig_mpz;
|
||||
|
||||
(void)digest_len;
|
||||
|
||||
if (key == NULL)
|
||||
{
|
||||
if (!(key = whine_malloc(sizeof(struct rsa_public_key))))
|
||||
return 0;
|
||||
|
||||
nettle_rsa_public_key_init(key);
|
||||
mpz_init(sig_mpz);
|
||||
}
|
||||
|
||||
if ((key_len < 3) || !(p = blockdata_retrieve(key_data, key_len, NULL)))
|
||||
return 0;
|
||||
|
||||
key_len--;
|
||||
if ((exp_len = *p++) == 0)
|
||||
{
|
||||
GETSHORT(exp_len, p);
|
||||
key_len -= 2;
|
||||
}
|
||||
|
||||
if (exp_len >= key_len)
|
||||
return 0;
|
||||
|
||||
key->size = key_len - exp_len;
|
||||
mpz_import(key->e, exp_len, 1, 1, 0, 0, p);
|
||||
mpz_import(key->n, key->size, 1, 1, 0, 0, p + exp_len);
|
||||
|
||||
mpz_import(sig_mpz, sig_len, 1, 1, 0, 0, sig);
|
||||
|
||||
switch (algo)
|
||||
{
|
||||
case 1:
|
||||
return nettle_rsa_md5_verify_digest(key, digest, sig_mpz);
|
||||
case 5: case 7:
|
||||
return nettle_rsa_sha1_verify_digest(key, digest, sig_mpz);
|
||||
case 8:
|
||||
return nettle_rsa_sha256_verify_digest(key, digest, sig_mpz);
|
||||
case 10:
|
||||
return nettle_rsa_sha512_verify_digest(key, digest, sig_mpz);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dnsmasq_dsa_verify(struct blockdata *key_data, unsigned int key_len, unsigned char *sig, size_t sig_len,
|
||||
unsigned char *digest, size_t digest_len, int algo)
|
||||
{
|
||||
unsigned char *p;
|
||||
unsigned int t;
|
||||
|
||||
static mpz_t y;
|
||||
static struct dsa_params *params = NULL;
|
||||
static struct dsa_signature *sig_struct;
|
||||
|
||||
(void)digest_len;
|
||||
|
||||
if (params == NULL)
|
||||
{
|
||||
if (!(sig_struct = whine_malloc(sizeof(struct dsa_signature))) ||
|
||||
!(params = whine_malloc(sizeof(struct dsa_params))))
|
||||
return 0;
|
||||
|
||||
mpz_init(y);
|
||||
nettle_dsa_params_init(params);
|
||||
nettle_dsa_signature_init(sig_struct);
|
||||
}
|
||||
|
||||
if ((sig_len < 41) || !(p = blockdata_retrieve(key_data, key_len, NULL)))
|
||||
return 0;
|
||||
|
||||
t = *p++;
|
||||
|
||||
if (key_len < (213 + (t * 24)))
|
||||
return 0;
|
||||
|
||||
mpz_import(params->q, 20, 1, 1, 0, 0, p); p += 20;
|
||||
mpz_import(params->p, 64 + (t*8), 1, 1, 0, 0, p); p += 64 + (t*8);
|
||||
mpz_import(params->g, 64 + (t*8), 1, 1, 0, 0, p); p += 64 + (t*8);
|
||||
mpz_import(y, 64 + (t*8), 1, 1, 0, 0, p); p += 64 + (t*8);
|
||||
|
||||
mpz_import(sig_struct->r, 20, 1, 1, 0, 0, sig+1);
|
||||
mpz_import(sig_struct->s, 20, 1, 1, 0, 0, sig+21);
|
||||
|
||||
(void)algo;
|
||||
|
||||
return nettle_dsa_verify(params, y, digest_len, digest, sig_struct);
|
||||
}
|
||||
|
||||
static int dnsmasq_ecdsa_verify(struct blockdata *key_data, unsigned int key_len,
|
||||
unsigned char *sig, size_t sig_len,
|
||||
unsigned char *digest, size_t digest_len, int algo)
|
||||
{
|
||||
unsigned char *p;
|
||||
unsigned int t;
|
||||
struct ecc_point *key;
|
||||
|
||||
static struct ecc_point *key_256 = NULL, *key_384 = NULL;
|
||||
static mpz_t x, y;
|
||||
static struct dsa_signature *sig_struct;
|
||||
|
||||
if (!sig_struct)
|
||||
{
|
||||
if (!(sig_struct = whine_malloc(sizeof(struct dsa_signature))))
|
||||
return 0;
|
||||
|
||||
nettle_dsa_signature_init(sig_struct);
|
||||
mpz_init(x);
|
||||
mpz_init(y);
|
||||
}
|
||||
|
||||
switch (algo)
|
||||
{
|
||||
case 13:
|
||||
if (!key_256)
|
||||
{
|
||||
if (!(key_256 = whine_malloc(sizeof(struct ecc_point))))
|
||||
return 0;
|
||||
|
||||
nettle_ecc_point_init(key_256, &nettle_secp_256r1);
|
||||
}
|
||||
|
||||
key = key_256;
|
||||
t = 32;
|
||||
break;
|
||||
|
||||
case 14:
|
||||
if (!key_384)
|
||||
{
|
||||
if (!(key_384 = whine_malloc(sizeof(struct ecc_point))))
|
||||
return 0;
|
||||
|
||||
nettle_ecc_point_init(key_384, &nettle_secp_384r1);
|
||||
}
|
||||
|
||||
key = key_384;
|
||||
t = 48;
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (sig_len != 2*t || key_len != 2*t ||
|
||||
!(p = blockdata_retrieve(key_data, key_len, NULL)))
|
||||
return 0;
|
||||
|
||||
mpz_import(x, t , 1, 1, 0, 0, p);
|
||||
mpz_import(y, t , 1, 1, 0, 0, p + t);
|
||||
|
||||
if (!ecc_point_set(key, x, y))
|
||||
return 0;
|
||||
|
||||
mpz_import(sig_struct->r, t, 1, 1, 0, 0, sig);
|
||||
mpz_import(sig_struct->s, t, 1, 1, 0, 0, sig + t);
|
||||
|
||||
return nettle_ecdsa_verify(key, digest_len, digest, sig_struct);
|
||||
}
|
||||
|
||||
static int dnsmasq_eddsa_verify(struct blockdata *key_data, unsigned int key_len,
|
||||
unsigned char *sig, size_t sig_len,
|
||||
unsigned char *digest, size_t digest_len, int algo)
|
||||
{
|
||||
unsigned char *p;
|
||||
|
||||
if (key_len != ED25519_KEY_SIZE ||
|
||||
sig_len != ED25519_SIGNATURE_SIZE ||
|
||||
digest_len != sizeof(struct null_hash_digest) ||
|
||||
!(p = blockdata_retrieve(key_data, key_len, NULL)))
|
||||
return 0;
|
||||
|
||||
/* The "digest" returned by the null_hash function is simply a struct null_hash_digest
|
||||
which has a pointer to the actual data and a length, because the buffer
|
||||
may need to be extended during "hashing". */
|
||||
|
||||
switch (algo)
|
||||
{
|
||||
case 15:
|
||||
return ed25519_sha512_verify(p,
|
||||
((struct null_hash_digest *)digest)->len,
|
||||
((struct null_hash_digest *)digest)->buff,
|
||||
sig);
|
||||
case 16:
|
||||
/* Ed448 when available */
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int (*verify_func(int algo))(struct blockdata *key_data, unsigned int key_len, unsigned char *sig, size_t sig_len,
|
||||
unsigned char *digest, size_t digest_len, int algo)
|
||||
{
|
||||
|
||||
/* Enure at runtime that we have support for this digest */
|
||||
if (!hash_find(algo_digest_name(algo)))
|
||||
return NULL;
|
||||
|
||||
/* This switch defines which sig algorithms we support, can't introspect Nettle for that. */
|
||||
switch (algo)
|
||||
{
|
||||
case 1: case 5: case 7: case 8: case 10:
|
||||
return dnsmasq_rsa_verify;
|
||||
|
||||
case 3: case 6:
|
||||
return dnsmasq_dsa_verify;
|
||||
|
||||
case 13: case 14:
|
||||
return dnsmasq_ecdsa_verify;
|
||||
|
||||
case 15: case 16:
|
||||
return dnsmasq_eddsa_verify;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int verify(struct blockdata *key_data, unsigned int key_len, unsigned char *sig, size_t sig_len,
|
||||
unsigned char *digest, size_t digest_len, int algo)
|
||||
{
|
||||
|
||||
int (*func)(struct blockdata *key_data, unsigned int key_len, unsigned char *sig, size_t sig_len,
|
||||
unsigned char *digest, size_t digest_len, int algo);
|
||||
|
||||
func = verify_func(algo);
|
||||
|
||||
if (!func)
|
||||
return 0;
|
||||
|
||||
return (*func)(key_data, key_len, sig, sig_len, digest, digest_len, algo);
|
||||
}
|
||||
|
||||
/* Note the ds_digest_name(), algo_digest_name() and nsec3_digest_name()
|
||||
define which algo numbers we support. If algo_digest_name() returns
|
||||
non-NULL for an algorithm number, we assume that algorithm is
|
||||
supported by verify(). */
|
||||
|
||||
/* http://www.iana.org/assignments/ds-rr-types/ds-rr-types.xhtml */
|
||||
char *ds_digest_name(int digest)
|
||||
{
|
||||
switch (digest)
|
||||
{
|
||||
case 1: return "sha1";
|
||||
case 2: return "sha256";
|
||||
case 3: return "gosthash94";
|
||||
case 4: return "sha384";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* http://www.iana.org/assignments/dns-sec-alg-numbers/dns-sec-alg-numbers.xhtml */
|
||||
char *algo_digest_name(int algo)
|
||||
{
|
||||
switch (algo)
|
||||
{
|
||||
case 1: return NULL; /* RSA/MD5 - Must Not Implement. RFC 6944 para 2.3. */
|
||||
case 2: return NULL; /* Diffie-Hellman */
|
||||
case 3: return "sha1"; /* DSA/SHA1 */
|
||||
case 5: return "sha1"; /* RSA/SHA1 */
|
||||
case 6: return "sha1"; /* DSA-NSEC3-SHA1 */
|
||||
case 7: return "sha1"; /* RSASHA1-NSEC3-SHA1 */
|
||||
case 8: return "sha256"; /* RSA/SHA-256 */
|
||||
case 10: return "sha512"; /* RSA/SHA-512 */
|
||||
case 12: return NULL; /* ECC-GOST */
|
||||
case 13: return "sha256"; /* ECDSAP256SHA256 */
|
||||
case 14: return "sha384"; /* ECDSAP384SHA384 */
|
||||
case 15: return "null_hash"; /* ED25519 */
|
||||
case 16: return NULL; /* ED448 */
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* http://www.iana.org/assignments/dnssec-nsec3-parameters/dnssec-nsec3-parameters.xhtml */
|
||||
char *nsec3_digest_name(int digest)
|
||||
{
|
||||
switch (digest)
|
||||
{
|
||||
case 1: return "sha1";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
424
src/dbus.c
424
src/dbus.c
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2014 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2018 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
|
||||
@@ -35,6 +35,11 @@ const char* introspection_xml_template =
|
||||
" <method name=\"GetVersion\">\n"
|
||||
" <arg name=\"version\" direction=\"out\" type=\"s\"/>\n"
|
||||
" </method>\n"
|
||||
#ifdef HAVE_LOOP
|
||||
" <method name=\"GetLoopServers\">\n"
|
||||
" <arg name=\"server\" direction=\"out\" type=\"as\"/>\n"
|
||||
" </method>\n"
|
||||
#endif
|
||||
" <method name=\"SetServers\">\n"
|
||||
" <arg name=\"servers\" direction=\"in\" type=\"av\"/>\n"
|
||||
" </method>\n"
|
||||
@@ -44,6 +49,12 @@ const char* introspection_xml_template =
|
||||
" <method name=\"SetServersEx\">\n"
|
||||
" <arg name=\"servers\" direction=\"in\" type=\"aas\"/>\n"
|
||||
" </method>\n"
|
||||
" <method name=\"SetFilterWin2KOption\">\n"
|
||||
" <arg name=\"filterwin2k\" direction=\"in\" type=\"b\"/>\n"
|
||||
" </method>\n"
|
||||
" <method name=\"SetBogusPrivOption\">\n"
|
||||
" <arg name=\"boguspriv\" direction=\"in\" type=\"b\"/>\n"
|
||||
" </method>\n"
|
||||
" <signal name=\"DhcpLeaseAdded\">\n"
|
||||
" <arg name=\"ipaddr\" type=\"s\"/>\n"
|
||||
" <arg name=\"hwaddr\" type=\"s\"/>\n"
|
||||
@@ -59,6 +70,21 @@ const char* introspection_xml_template =
|
||||
" <arg name=\"hwaddr\" type=\"s\"/>\n"
|
||||
" <arg name=\"hostname\" type=\"s\"/>\n"
|
||||
" </signal>\n"
|
||||
#ifdef HAVE_DHCP
|
||||
" <method name=\"AddDhcpLease\">\n"
|
||||
" <arg name=\"ipaddr\" type=\"s\"/>\n"
|
||||
" <arg name=\"hwaddr\" type=\"s\"/>\n"
|
||||
" <arg name=\"hostname\" type=\"ay\"/>\n"
|
||||
" <arg name=\"clid\" type=\"ay\"/>\n"
|
||||
" <arg name=\"lease_duration\" type=\"u\"/>\n"
|
||||
" <arg name=\"ia_id\" type=\"u\"/>\n"
|
||||
" <arg name=\"is_temporary\" type=\"b\"/>\n"
|
||||
" </method>\n"
|
||||
" <method name=\"DeleteDhcpLease\">\n"
|
||||
" <arg name=\"ipaddr\" type=\"s\"/>\n"
|
||||
" <arg name=\"success\" type=\"b\" direction=\"out\"/>\n"
|
||||
" </method>\n"
|
||||
#endif
|
||||
" </interface>\n"
|
||||
"</node>\n";
|
||||
|
||||
@@ -108,108 +134,6 @@ static void remove_watch(DBusWatch *watch, void *data)
|
||||
w = data; /* no warning */
|
||||
}
|
||||
|
||||
static void add_update_server(union mysockaddr *addr,
|
||||
union mysockaddr *source_addr,
|
||||
const char *interface,
|
||||
const char *domain)
|
||||
{
|
||||
struct server *serv;
|
||||
|
||||
/* See if there is a suitable candidate, and unmark */
|
||||
for (serv = daemon->servers; serv; serv = serv->next)
|
||||
if ((serv->flags & SERV_FROM_DBUS) &&
|
||||
(serv->flags & SERV_MARK))
|
||||
{
|
||||
if (domain)
|
||||
{
|
||||
if (!(serv->flags & SERV_HAS_DOMAIN) || !hostname_isequal(domain, serv->domain))
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (serv->flags & SERV_HAS_DOMAIN)
|
||||
continue;
|
||||
}
|
||||
|
||||
serv->flags &= ~SERV_MARK;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (!serv && (serv = whine_malloc(sizeof (struct server))))
|
||||
{
|
||||
/* Not found, create a new one. */
|
||||
memset(serv, 0, sizeof(struct server));
|
||||
|
||||
if (domain && !(serv->domain = whine_malloc(strlen(domain)+1)))
|
||||
{
|
||||
free(serv);
|
||||
serv = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
serv->next = daemon->servers;
|
||||
daemon->servers = serv;
|
||||
serv->flags = SERV_FROM_DBUS;
|
||||
if (domain)
|
||||
{
|
||||
strcpy(serv->domain, domain);
|
||||
serv->flags |= SERV_HAS_DOMAIN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (serv)
|
||||
{
|
||||
if (interface)
|
||||
strcpy(serv->interface, interface);
|
||||
else
|
||||
serv->interface[0] = 0;
|
||||
|
||||
if (source_addr->in.sin_family == AF_INET &&
|
||||
addr->in.sin_addr.s_addr == 0 &&
|
||||
serv->domain)
|
||||
serv->flags |= SERV_NO_ADDR;
|
||||
else
|
||||
{
|
||||
serv->flags &= ~SERV_NO_ADDR;
|
||||
serv->addr = *addr;
|
||||
serv->source_addr = *source_addr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void mark_dbus(void)
|
||||
{
|
||||
struct server *serv;
|
||||
|
||||
/* mark everything from DBUS */
|
||||
for (serv = daemon->servers; serv; serv = serv->next)
|
||||
if (serv->flags & SERV_FROM_DBUS)
|
||||
serv->flags |= SERV_MARK;
|
||||
}
|
||||
|
||||
static void cleanup_dbus()
|
||||
{
|
||||
struct server *serv, *tmp, **up;
|
||||
|
||||
/* unlink and free anything still marked. */
|
||||
for (serv = daemon->servers, up = &daemon->servers; serv; serv = tmp)
|
||||
{
|
||||
tmp = serv->next;
|
||||
if (serv->flags & SERV_MARK)
|
||||
{
|
||||
server_gone(serv);
|
||||
*up = serv->next;
|
||||
if (serv->domain)
|
||||
free(serv->domain);
|
||||
free(serv);
|
||||
}
|
||||
else
|
||||
up = &serv->next;
|
||||
}
|
||||
}
|
||||
|
||||
static void dbus_read_servers(DBusMessage *message)
|
||||
{
|
||||
DBusMessageIter iter;
|
||||
@@ -218,8 +142,8 @@ static void dbus_read_servers(DBusMessage *message)
|
||||
|
||||
dbus_message_iter_init(message, &iter);
|
||||
|
||||
mark_dbus();
|
||||
|
||||
mark_servers(SERV_FROM_DBUS);
|
||||
|
||||
while (1)
|
||||
{
|
||||
int skip = 0;
|
||||
@@ -252,13 +176,16 @@ static void dbus_read_servers(DBusMessage *message)
|
||||
dbus_message_iter_get_basic(&iter, &p[i]);
|
||||
dbus_message_iter_next (&iter);
|
||||
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_BYTE)
|
||||
break;
|
||||
{
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef HAVE_IPV6
|
||||
my_syslog(LOG_WARNING, _("attempt to set an IPv6 server address via DBus - no IPv6 support"));
|
||||
#else
|
||||
if (i == sizeof(struct in6_addr)-1)
|
||||
if (i == sizeof(struct in6_addr))
|
||||
{
|
||||
memcpy(&addr.in6.sin6_addr, p, sizeof(struct in6_addr));
|
||||
#ifdef HAVE_SOCKADDR_SA_LEN
|
||||
@@ -289,15 +216,38 @@ static void dbus_read_servers(DBusMessage *message)
|
||||
domain = NULL;
|
||||
|
||||
if (!skip)
|
||||
add_update_server(&addr, &source_addr, NULL, domain);
|
||||
add_update_server(SERV_FROM_DBUS, &addr, &source_addr, NULL, domain);
|
||||
|
||||
} while (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_STRING);
|
||||
}
|
||||
|
||||
/* unlink and free anything still marked. */
|
||||
cleanup_dbus();
|
||||
cleanup_servers();
|
||||
}
|
||||
|
||||
#ifdef HAVE_LOOP
|
||||
static DBusMessage *dbus_reply_server_loop(DBusMessage *message)
|
||||
{
|
||||
DBusMessageIter args, args_iter;
|
||||
struct server *serv;
|
||||
DBusMessage *reply = dbus_message_new_method_return(message);
|
||||
|
||||
dbus_message_iter_init_append (reply, &args);
|
||||
dbus_message_iter_open_container (&args, DBUS_TYPE_ARRAY,DBUS_TYPE_STRING_AS_STRING, &args_iter);
|
||||
|
||||
for (serv = daemon->servers; serv; serv = serv->next)
|
||||
if (serv->flags & SERV_LOOP)
|
||||
{
|
||||
prettyprint_addr(&serv->addr, daemon->addrbuff);
|
||||
dbus_message_iter_append_basic (&args_iter, DBUS_TYPE_STRING, &daemon->addrbuff);
|
||||
}
|
||||
|
||||
dbus_message_iter_close_container (&args, &args_iter);
|
||||
|
||||
return reply;
|
||||
}
|
||||
#endif
|
||||
|
||||
static DBusMessage* dbus_read_servers_ex(DBusMessage *message, int strings)
|
||||
{
|
||||
DBusMessageIter iter, array_iter, string_iter;
|
||||
@@ -319,7 +269,7 @@ static DBusMessage* dbus_read_servers_ex(DBusMessage *message, int strings)
|
||||
strings ? "Expected array of string" : "Expected array of string arrays");
|
||||
}
|
||||
|
||||
mark_dbus();
|
||||
mark_servers(SERV_FROM_DBUS);
|
||||
|
||||
/* array_iter points to each "as" element in the outer array */
|
||||
dbus_message_iter_recurse(&iter, &array_iter);
|
||||
@@ -327,6 +277,7 @@ static DBusMessage* dbus_read_servers_ex(DBusMessage *message, int strings)
|
||||
{
|
||||
const char *str = NULL;
|
||||
union mysockaddr addr, source_addr;
|
||||
int flags = 0;
|
||||
char interface[IF_NAMESIZE];
|
||||
char *str_addr, *str_domain = NULL;
|
||||
|
||||
@@ -416,16 +367,19 @@ static DBusMessage* dbus_read_servers_ex(DBusMessage *message, int strings)
|
||||
memset(&interface, 0, sizeof(interface));
|
||||
|
||||
/* parse the IP address */
|
||||
addr_err = parse_server(str_addr, &addr, &source_addr, (char *) &interface, NULL);
|
||||
|
||||
if (addr_err)
|
||||
{
|
||||
if ((addr_err = parse_server(str_addr, &addr, &source_addr, (char *) &interface, &flags)))
|
||||
{
|
||||
error = dbus_message_new_error_printf(message, DBUS_ERROR_INVALID_ARGS,
|
||||
"Invalid IP address '%s': %s",
|
||||
str, addr_err);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* 0.0.0.0 for server address == NULL, for Dbus */
|
||||
if (addr.in.sin_family == AF_INET &&
|
||||
addr.in.sin_addr.s_addr == 0)
|
||||
flags |= SERV_NO_ADDR;
|
||||
|
||||
if (strings)
|
||||
{
|
||||
char *p;
|
||||
@@ -439,7 +393,7 @@ static DBusMessage* dbus_read_servers_ex(DBusMessage *message, int strings)
|
||||
else
|
||||
p = NULL;
|
||||
|
||||
add_update_server(&addr, &source_addr, interface, str_domain);
|
||||
add_update_server(flags | SERV_FROM_DBUS, &addr, &source_addr, interface, str_domain);
|
||||
} while ((str_domain = p));
|
||||
}
|
||||
else
|
||||
@@ -454,7 +408,7 @@ static DBusMessage* dbus_read_servers_ex(DBusMessage *message, int strings)
|
||||
dbus_message_iter_get_basic(&string_iter, &str);
|
||||
dbus_message_iter_next (&string_iter);
|
||||
|
||||
add_update_server(&addr, &source_addr, interface, str);
|
||||
add_update_server(flags | SERV_FROM_DBUS, &addr, &source_addr, interface, str);
|
||||
} while (dbus_message_iter_get_arg_type(&string_iter) == DBUS_TYPE_STRING);
|
||||
}
|
||||
|
||||
@@ -462,7 +416,7 @@ static DBusMessage* dbus_read_servers_ex(DBusMessage *message, int strings)
|
||||
dbus_message_iter_next(&array_iter);
|
||||
}
|
||||
|
||||
cleanup_dbus();
|
||||
cleanup_servers();
|
||||
|
||||
if (dup)
|
||||
free(dup);
|
||||
@@ -470,6 +424,195 @@ static DBusMessage* dbus_read_servers_ex(DBusMessage *message, int strings)
|
||||
return error;
|
||||
}
|
||||
|
||||
static DBusMessage *dbus_set_bool(DBusMessage *message, int flag, char *name)
|
||||
{
|
||||
DBusMessageIter iter;
|
||||
dbus_bool_t enabled;
|
||||
|
||||
if (!dbus_message_iter_init(message, &iter) || dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_BOOLEAN)
|
||||
return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, "Expected boolean argument");
|
||||
|
||||
dbus_message_iter_get_basic(&iter, &enabled);
|
||||
|
||||
if (enabled)
|
||||
{
|
||||
my_syslog(LOG_INFO, _("Enabling --%s option from D-Bus"), name);
|
||||
set_option_bool(flag);
|
||||
}
|
||||
else
|
||||
{
|
||||
my_syslog(LOG_INFO, _("Disabling --%s option from D-Bus"), name);
|
||||
reset_option_bool(flag);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef HAVE_DHCP
|
||||
static DBusMessage *dbus_add_lease(DBusMessage* message)
|
||||
{
|
||||
struct dhcp_lease *lease;
|
||||
const char *ipaddr, *hwaddr, *hostname, *tmp;
|
||||
const unsigned char* clid;
|
||||
int clid_len, hostname_len, hw_len, hw_type;
|
||||
dbus_uint32_t expires, ia_id;
|
||||
dbus_bool_t is_temporary;
|
||||
struct all_addr addr;
|
||||
time_t now = dnsmasq_time();
|
||||
unsigned char dhcp_chaddr[DHCP_CHADDR_MAX];
|
||||
|
||||
DBusMessageIter iter, array_iter;
|
||||
if (!dbus_message_iter_init(message, &iter))
|
||||
return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
|
||||
"Failed to initialize dbus message iter");
|
||||
|
||||
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
|
||||
return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
|
||||
"Expected string as first argument");
|
||||
|
||||
dbus_message_iter_get_basic(&iter, &ipaddr);
|
||||
dbus_message_iter_next(&iter);
|
||||
|
||||
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
|
||||
return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
|
||||
"Expected string as second argument");
|
||||
|
||||
dbus_message_iter_get_basic(&iter, &hwaddr);
|
||||
dbus_message_iter_next(&iter);
|
||||
|
||||
if ((dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) ||
|
||||
(dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_BYTE))
|
||||
return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
|
||||
"Expected byte array as third argument");
|
||||
|
||||
dbus_message_iter_recurse(&iter, &array_iter);
|
||||
dbus_message_iter_get_fixed_array(&array_iter, &hostname, &hostname_len);
|
||||
tmp = memchr(hostname, '\0', hostname_len);
|
||||
if (tmp)
|
||||
{
|
||||
if (tmp == &hostname[hostname_len - 1])
|
||||
hostname_len--;
|
||||
else
|
||||
return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
|
||||
"Hostname contains an embedded NUL character");
|
||||
}
|
||||
dbus_message_iter_next(&iter);
|
||||
|
||||
if ((dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) ||
|
||||
(dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_BYTE))
|
||||
return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
|
||||
"Expected byte array as fourth argument");
|
||||
|
||||
dbus_message_iter_recurse(&iter, &array_iter);
|
||||
dbus_message_iter_get_fixed_array(&array_iter, &clid, &clid_len);
|
||||
dbus_message_iter_next(&iter);
|
||||
|
||||
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT32)
|
||||
return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
|
||||
"Expected uint32 as fifth argument");
|
||||
|
||||
dbus_message_iter_get_basic(&iter, &expires);
|
||||
dbus_message_iter_next(&iter);
|
||||
|
||||
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT32)
|
||||
return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
|
||||
"Expected uint32 as sixth argument");
|
||||
|
||||
dbus_message_iter_get_basic(&iter, &ia_id);
|
||||
dbus_message_iter_next(&iter);
|
||||
|
||||
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_BOOLEAN)
|
||||
return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
|
||||
"Expected uint32 as sixth argument");
|
||||
|
||||
dbus_message_iter_get_basic(&iter, &is_temporary);
|
||||
|
||||
if (inet_pton(AF_INET, ipaddr, &addr.addr.addr4))
|
||||
{
|
||||
if (ia_id != 0 || is_temporary)
|
||||
return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
|
||||
"ia_id and is_temporary must be zero for IPv4 lease");
|
||||
|
||||
if (!(lease = lease_find_by_addr(addr.addr.addr4)))
|
||||
lease = lease4_allocate(addr.addr.addr4);
|
||||
}
|
||||
#ifdef HAVE_DHCP6
|
||||
else if (inet_pton(AF_INET6, ipaddr, &addr.addr.addr6))
|
||||
{
|
||||
if (!(lease = lease6_find_by_addr(&addr.addr.addr6, 128, 0)))
|
||||
lease = lease6_allocate(&addr.addr.addr6,
|
||||
is_temporary ? LEASE_TA : LEASE_NA);
|
||||
lease_set_iaid(lease, ia_id);
|
||||
}
|
||||
#endif
|
||||
else
|
||||
return dbus_message_new_error_printf(message, DBUS_ERROR_INVALID_ARGS,
|
||||
"Invalid IP address '%s'", ipaddr);
|
||||
|
||||
hw_len = parse_hex((char*)hwaddr, dhcp_chaddr, DHCP_CHADDR_MAX, NULL, &hw_type);
|
||||
if (hw_type == 0 && hw_len != 0)
|
||||
hw_type = ARPHRD_ETHER;
|
||||
|
||||
lease_set_hwaddr(lease, dhcp_chaddr, clid, hw_len, hw_type,
|
||||
clid_len, now, 0);
|
||||
lease_set_expires(lease, expires, now);
|
||||
if (hostname_len != 0)
|
||||
lease_set_hostname(lease, hostname, 0, get_domain(lease->addr), NULL);
|
||||
|
||||
lease_update_file(now);
|
||||
lease_update_dns(0);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static DBusMessage *dbus_del_lease(DBusMessage* message)
|
||||
{
|
||||
struct dhcp_lease *lease;
|
||||
DBusMessageIter iter;
|
||||
const char *ipaddr;
|
||||
DBusMessage *reply;
|
||||
struct all_addr addr;
|
||||
dbus_bool_t ret = 1;
|
||||
time_t now = dnsmasq_time();
|
||||
|
||||
if (!dbus_message_iter_init(message, &iter))
|
||||
return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
|
||||
"Failed to initialize dbus message iter");
|
||||
|
||||
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
|
||||
return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
|
||||
"Expected string as first argument");
|
||||
|
||||
dbus_message_iter_get_basic(&iter, &ipaddr);
|
||||
|
||||
if (inet_pton(AF_INET, ipaddr, &addr.addr.addr4))
|
||||
lease = lease_find_by_addr(addr.addr.addr4);
|
||||
#ifdef HAVE_DHCP6
|
||||
else if (inet_pton(AF_INET6, ipaddr, &addr.addr.addr6))
|
||||
lease = lease6_find_by_addr(&addr.addr.addr6, 128, 0);
|
||||
#endif
|
||||
else
|
||||
return dbus_message_new_error_printf(message, DBUS_ERROR_INVALID_ARGS,
|
||||
"Invalid IP address '%s'", ipaddr);
|
||||
|
||||
if (lease)
|
||||
{
|
||||
lease_prune(lease, now);
|
||||
lease_update_file(now);
|
||||
lease_update_dns(0);
|
||||
}
|
||||
else
|
||||
ret = 0;
|
||||
|
||||
if ((reply = dbus_message_new_method_return(message)))
|
||||
dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &ret,
|
||||
DBUS_TYPE_INVALID);
|
||||
|
||||
|
||||
return reply;
|
||||
}
|
||||
#endif
|
||||
|
||||
DBusHandlerResult message_handler(DBusConnection *connection,
|
||||
DBusMessage *message,
|
||||
void *user_data)
|
||||
@@ -498,6 +641,12 @@ DBusHandlerResult message_handler(DBusConnection *connection,
|
||||
|
||||
dbus_message_append_args(reply, DBUS_TYPE_STRING, &v, DBUS_TYPE_INVALID);
|
||||
}
|
||||
#ifdef HAVE_LOOP
|
||||
else if (strcmp(method, "GetLoopServers") == 0)
|
||||
{
|
||||
reply = dbus_reply_server_loop(message);
|
||||
}
|
||||
#endif
|
||||
else if (strcmp(method, "SetServers") == 0)
|
||||
{
|
||||
dbus_read_servers(message);
|
||||
@@ -513,6 +662,24 @@ DBusHandlerResult message_handler(DBusConnection *connection,
|
||||
reply = dbus_read_servers_ex(message, 1);
|
||||
new_servers = 1;
|
||||
}
|
||||
else if (strcmp(method, "SetFilterWin2KOption") == 0)
|
||||
{
|
||||
reply = dbus_set_bool(message, OPT_FILTER, "filterwin2k");
|
||||
}
|
||||
else if (strcmp(method, "SetBogusPrivOption") == 0)
|
||||
{
|
||||
reply = dbus_set_bool(message, OPT_BOGUSPRIV, "bogus-priv");
|
||||
}
|
||||
#ifdef HAVE_DHCP
|
||||
else if (strcmp(method, "AddDhcpLease") == 0)
|
||||
{
|
||||
reply = dbus_add_lease(message);
|
||||
}
|
||||
else if (strcmp(method, "DeleteDhcpLease") == 0)
|
||||
{
|
||||
reply = dbus_del_lease(message);
|
||||
}
|
||||
#endif
|
||||
else if (strcmp(method, "ClearCache") == 0)
|
||||
clear_cache = 1;
|
||||
else
|
||||
@@ -581,8 +748,7 @@ char *dbus_init(void)
|
||||
}
|
||||
|
||||
|
||||
void set_dbus_listeners(int *maxfdp,
|
||||
fd_set *rset, fd_set *wset, fd_set *eset)
|
||||
void set_dbus_listeners(void)
|
||||
{
|
||||
struct watch *w;
|
||||
|
||||
@@ -592,19 +758,17 @@ void set_dbus_listeners(int *maxfdp,
|
||||
unsigned int flags = dbus_watch_get_flags(w->watch);
|
||||
int fd = dbus_watch_get_unix_fd(w->watch);
|
||||
|
||||
bump_maxfd(fd, maxfdp);
|
||||
|
||||
if (flags & DBUS_WATCH_READABLE)
|
||||
FD_SET(fd, rset);
|
||||
poll_listen(fd, POLLIN);
|
||||
|
||||
if (flags & DBUS_WATCH_WRITABLE)
|
||||
FD_SET(fd, wset);
|
||||
poll_listen(fd, POLLOUT);
|
||||
|
||||
FD_SET(fd, eset);
|
||||
poll_listen(fd, POLLERR);
|
||||
}
|
||||
}
|
||||
|
||||
void check_dbus_listeners(fd_set *rset, fd_set *wset, fd_set *eset)
|
||||
void check_dbus_listeners()
|
||||
{
|
||||
DBusConnection *connection = (DBusConnection *)daemon->dbus;
|
||||
struct watch *w;
|
||||
@@ -615,13 +779,13 @@ void check_dbus_listeners(fd_set *rset, fd_set *wset, fd_set *eset)
|
||||
unsigned int flags = 0;
|
||||
int fd = dbus_watch_get_unix_fd(w->watch);
|
||||
|
||||
if (FD_ISSET(fd, rset))
|
||||
if (poll_check(fd, POLLIN))
|
||||
flags |= DBUS_WATCH_READABLE;
|
||||
|
||||
if (FD_ISSET(fd, wset))
|
||||
if (poll_check(fd, POLLOUT))
|
||||
flags |= DBUS_WATCH_WRITABLE;
|
||||
|
||||
if (FD_ISSET(fd, eset))
|
||||
if (poll_check(fd, POLLERR))
|
||||
flags |= DBUS_WATCH_ERROR;
|
||||
|
||||
if (flags != 0)
|
||||
@@ -656,7 +820,7 @@ void emit_dbus_signal(int action, struct dhcp_lease *lease, char *hostname)
|
||||
if (lease->flags & (LEASE_TA | LEASE_NA))
|
||||
{
|
||||
print_mac(mac, lease->clid, lease->clid_len);
|
||||
inet_ntop(AF_INET6, lease->hwaddr, daemon->addrbuff, ADDRSTRLEN);
|
||||
inet_ntop(AF_INET6, &lease->addr6, daemon->addrbuff, ADDRSTRLEN);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2014 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2018 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
|
||||
@@ -20,11 +20,11 @@
|
||||
|
||||
void dhcp_common_init(void)
|
||||
{
|
||||
/* These each hold a DHCP option max size 255
|
||||
and get a terminating zero added */
|
||||
daemon->dhcp_buff = safe_malloc(256);
|
||||
daemon->dhcp_buff2 = safe_malloc(256);
|
||||
daemon->dhcp_buff3 = safe_malloc(256);
|
||||
/* These each hold a DHCP option max size 255
|
||||
and get a terminating zero added */
|
||||
daemon->dhcp_buff = safe_malloc(DHCP_BUFF_SZ);
|
||||
daemon->dhcp_buff2 = safe_malloc(DHCP_BUFF_SZ);
|
||||
daemon->dhcp_buff3 = safe_malloc(DHCP_BUFF_SZ);
|
||||
|
||||
/* dhcp_packet is used by v4 and v6, outpacket only by v6
|
||||
sizeof(struct dhcp_packet) is as good an initial size as any,
|
||||
@@ -485,11 +485,8 @@ char *whichdevice(void)
|
||||
|
||||
void bindtodevice(char *device, int fd)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
|
||||
strcpy(ifr.ifr_name, device);
|
||||
/* only allowed by root. */
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr)) == -1 &&
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, device, IFNAMSIZ) == -1 &&
|
||||
errno != EPERM)
|
||||
die(_("failed to set SO_BINDTODEVICE on DHCP socket: %s"), NULL, EC_BADNET);
|
||||
}
|
||||
@@ -545,8 +542,8 @@ static const struct opttab_t {
|
||||
{ "parameter-request", 55, OT_INTERNAL },
|
||||
{ "message", 56, OT_INTERNAL },
|
||||
{ "max-message-size", 57, OT_INTERNAL },
|
||||
{ "T1", 58, OT_INTERNAL | OT_TIME},
|
||||
{ "T2", 59, OT_INTERNAL | OT_TIME},
|
||||
{ "T1", 58, OT_TIME},
|
||||
{ "T2", 59, OT_TIME},
|
||||
{ "vendor-class", 60, 0 },
|
||||
{ "client-id", 61, OT_INTERNAL },
|
||||
{ "nis+-domain", 64, OT_NAME },
|
||||
@@ -559,6 +556,7 @@ static const struct opttab_t {
|
||||
{ "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-id", 82, OT_INTERNAL },
|
||||
{ "client-arch", 93, 2 | OT_DEC },
|
||||
@@ -599,7 +597,7 @@ static const struct opttab_t opttab6[] = {
|
||||
{ "sntp-server", 31, OT_ADDR_LIST },
|
||||
{ "information-refresh-time", 32, OT_TIME },
|
||||
{ "FQDN", 39, OT_INTERNAL | OT_RFC1035_NAME },
|
||||
{ "ntp-server", 56, OT_ADDR_LIST },
|
||||
{ "ntp-server", 56, 0 },
|
||||
{ "bootfile-url", 59, OT_NAME },
|
||||
{ "bootfile-param", 60, OT_CSTRING },
|
||||
{ NULL, 0, 0 }
|
||||
@@ -855,14 +853,14 @@ void log_context(int family, struct dhcp_context *context)
|
||||
if (context->flags & CONTEXT_RA_STATELESS)
|
||||
{
|
||||
if (context->flags & CONTEXT_TEMPLATE)
|
||||
strncpy(daemon->dhcp_buff, context->template_interface, 256);
|
||||
strncpy(daemon->dhcp_buff, context->template_interface, DHCP_BUFF_SZ);
|
||||
else
|
||||
strcpy(daemon->dhcp_buff, daemon->addrbuff);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
inet_ntop(family, start, daemon->dhcp_buff, 256);
|
||||
inet_ntop(family, end, daemon->dhcp_buff3, 256);
|
||||
inet_ntop(family, start, daemon->dhcp_buff, DHCP_BUFF_SZ);
|
||||
inet_ntop(family, end, daemon->dhcp_buff3, DHCP_BUFF_SZ);
|
||||
my_syslog(MS_DHCP | LOG_INFO,
|
||||
(context->flags & CONTEXT_RA_STATELESS) ?
|
||||
_("%s stateless on %s%.0s%.0s%s") :
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2014 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2018 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
|
||||
@@ -19,6 +19,10 @@
|
||||
#define DHCP_CLIENT_ALTPORT 1068
|
||||
#define PXE_PORT 4011
|
||||
|
||||
/* These each hold a DHCP option max size 255
|
||||
and get a terminating zero added */
|
||||
#define DHCP_BUFF_SZ 256
|
||||
|
||||
#define BOOTREQUEST 1
|
||||
#define BOOTREPLY 2
|
||||
#define DHCP_COOKIE 0x63825363
|
||||
@@ -50,6 +54,7 @@
|
||||
#define OPTION_SNAME 66
|
||||
#define OPTION_FILENAME 67
|
||||
#define OPTION_USER_CLASS 77
|
||||
#define OPTION_RAPID_COMMIT 80
|
||||
#define OPTION_CLIENT_FQDN 81
|
||||
#define OPTION_AGENT_ID 82
|
||||
#define OPTION_ARCH 93
|
||||
|
||||
250
src/dhcp.c
250
src/dhcp.c
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2014 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2018 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
|
||||
@@ -67,9 +67,9 @@ static int make_fd(int port)
|
||||
setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &oneopt, sizeof(oneopt)) == -1)
|
||||
die(_("failed to set options on DHCP socket: %s"), NULL, EC_BADNET);
|
||||
|
||||
/* When bind-interfaces is set, there might be more than one dnmsasq
|
||||
/* When bind-interfaces is set, there might be more than one dnsmasq
|
||||
instance binding port 67. That's OK if they serve different networks.
|
||||
Need to set REUSEADDR|REUSEPORT to make this posible.
|
||||
Need to set REUSEADDR|REUSEPORT to make this possible.
|
||||
Handle the case that REUSEPORT is defined, but the kernel doesn't
|
||||
support it. This handles the introduction of REUSEPORT on Linux. */
|
||||
if (option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND))
|
||||
@@ -145,11 +145,14 @@ void dhcp_packet(time_t now, int pxe_fd)
|
||||
struct cmsghdr *cmptr;
|
||||
struct iovec iov;
|
||||
ssize_t sz;
|
||||
int iface_index = 0, unicast_dest = 0, is_inform = 0;
|
||||
int iface_index = 0, unicast_dest = 0, is_inform = 0, loopback = 0;
|
||||
int rcvd_iface_index;
|
||||
struct in_addr iface_addr;
|
||||
struct iface_param parm;
|
||||
time_t recvtime = now;
|
||||
#ifdef HAVE_LINUX_NETWORK
|
||||
struct arpreq arp_req;
|
||||
struct timeval tv;
|
||||
#endif
|
||||
|
||||
union {
|
||||
@@ -176,6 +179,9 @@ void dhcp_packet(time_t now, int pxe_fd)
|
||||
return;
|
||||
|
||||
#if defined (HAVE_LINUX_NETWORK)
|
||||
if (ioctl(fd, SIOCGSTAMP, &tv) == 0)
|
||||
recvtime = tv.tv_sec;
|
||||
|
||||
if (msg.msg_controllen >= sizeof(struct cmsghdr))
|
||||
for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
|
||||
if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_PKTINFO)
|
||||
@@ -217,26 +223,34 @@ void dhcp_packet(time_t now, int pxe_fd)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!indextoname(daemon->dhcpfd, iface_index, ifr.ifr_name))
|
||||
if (!indextoname(daemon->dhcpfd, iface_index, ifr.ifr_name) ||
|
||||
ioctl(daemon->dhcpfd, SIOCGIFFLAGS, &ifr) != 0)
|
||||
return;
|
||||
|
||||
|
||||
mess = (struct dhcp_packet *)daemon->dhcp_packet.iov_base;
|
||||
loopback = !mess->giaddr.s_addr && (ifr.ifr_flags & IFF_LOOPBACK);
|
||||
|
||||
#ifdef HAVE_LINUX_NETWORK
|
||||
/* ARP fiddling uses original interface even if we pretend to use a different one. */
|
||||
strncpy(arp_req.arp_dev, ifr.ifr_name, 16);
|
||||
#endif
|
||||
|
||||
/* One form of bridging on BSD has the property that packets
|
||||
can be recieved on bridge interfaces which do not have an IP address.
|
||||
We allow these to be treated as aliases of another interface which does have
|
||||
an IP address with --dhcp-bridge=interface,alias,alias */
|
||||
/* If the interface on which the DHCP request was received is an
|
||||
alias of some other interface (as specified by the
|
||||
--bridge-interface option), change ifr.ifr_name so that we look
|
||||
for DHCP contexts associated with the aliased interface instead
|
||||
of with the aliasing one. */
|
||||
rcvd_iface_index = iface_index;
|
||||
for (bridge = daemon->bridges; bridge; bridge = bridge->next)
|
||||
{
|
||||
for (alias = bridge->alias; alias; alias = alias->next)
|
||||
if (strncmp(ifr.ifr_name, alias->iface, IF_NAMESIZE) == 0)
|
||||
if (wildcard_matchn(alias->iface, ifr.ifr_name, IF_NAMESIZE))
|
||||
{
|
||||
if (!(iface_index = if_nametoindex(bridge->iface)))
|
||||
{
|
||||
my_syslog(LOG_WARNING, _("unknown interface %s in bridge-interface"), ifr.ifr_name);
|
||||
my_syslog(MS_DHCP | LOG_WARNING,
|
||||
_("unknown interface %s in bridge-interface"),
|
||||
bridge->iface);
|
||||
return;
|
||||
}
|
||||
else
|
||||
@@ -259,8 +273,8 @@ void dhcp_packet(time_t now, int pxe_fd)
|
||||
if ((relay = relay_reply4((struct dhcp_packet *)daemon->dhcp_packet.iov_base, ifr.ifr_name)))
|
||||
{
|
||||
/* Reply from server, using us as relay. */
|
||||
iface_index = relay->iface_index;
|
||||
if (!indextoname(daemon->dhcpfd, iface_index, ifr.ifr_name))
|
||||
rcvd_iface_index = relay->iface_index;
|
||||
if (!indextoname(daemon->dhcpfd, rcvd_iface_index, ifr.ifr_name))
|
||||
return;
|
||||
is_relay_reply = 1;
|
||||
iov.iov_len = sz;
|
||||
@@ -275,7 +289,8 @@ void dhcp_packet(time_t now, int pxe_fd)
|
||||
iface_addr = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr;
|
||||
else
|
||||
{
|
||||
my_syslog(MS_DHCP | LOG_WARNING, _("DHCP packet received on %s which has no address"), ifr.ifr_name);
|
||||
if (iface_check(AF_INET, NULL, ifr.ifr_name, NULL))
|
||||
my_syslog(MS_DHCP | LOG_WARNING, _("DHCP packet received on %s which has no address"), ifr.ifr_name);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -320,7 +335,7 @@ void dhcp_packet(time_t now, int pxe_fd)
|
||||
|
||||
/* We're relaying this request */
|
||||
if (parm.relay_local.s_addr != 0 &&
|
||||
relay_upstream4(parm.relay, (struct dhcp_packet *)daemon->dhcp_packet.iov_base, (size_t)sz, iface_index))
|
||||
relay_upstream4(parm.relay, mess, (size_t)sz, iface_index))
|
||||
return;
|
||||
|
||||
/* May have configured relay, but not DHCP server */
|
||||
@@ -329,14 +344,14 @@ void dhcp_packet(time_t now, int pxe_fd)
|
||||
|
||||
lease_prune(NULL, now); /* lose any expired leases */
|
||||
iov.iov_len = dhcp_reply(parm.current, ifr.ifr_name, iface_index, (size_t)sz,
|
||||
now, unicast_dest, &is_inform, pxe_fd, iface_addr);
|
||||
now, unicast_dest, loopback, &is_inform, pxe_fd, iface_addr, recvtime);
|
||||
lease_update_file(now);
|
||||
lease_update_dns(0);
|
||||
|
||||
if (iov.iov_len == 0)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
msg.msg_name = &dest;
|
||||
msg.msg_namelen = sizeof(dest);
|
||||
msg.msg_control = NULL;
|
||||
@@ -376,35 +391,41 @@ void dhcp_packet(time_t now, int pxe_fd)
|
||||
}
|
||||
}
|
||||
#if defined(HAVE_LINUX_NETWORK)
|
||||
else if ((ntohs(mess->flags) & 0x8000) || mess->hlen == 0 ||
|
||||
mess->hlen > sizeof(ifr.ifr_addr.sa_data) || mess->htype == 0)
|
||||
else
|
||||
{
|
||||
/* broadcast to 255.255.255.255 (or mac address invalid) */
|
||||
/* fill cmsg for outbound interface (both broadcast & unicast) */
|
||||
struct in_pktinfo *pkt;
|
||||
msg.msg_control = control_u.control;
|
||||
msg.msg_controllen = sizeof(control_u);
|
||||
cmptr = CMSG_FIRSTHDR(&msg);
|
||||
pkt = (struct in_pktinfo *)CMSG_DATA(cmptr);
|
||||
pkt->ipi_ifindex = iface_index;
|
||||
pkt->ipi_ifindex = rcvd_iface_index;
|
||||
pkt->ipi_spec_dst.s_addr = 0;
|
||||
msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
|
||||
cmptr->cmsg_level = IPPROTO_IP;
|
||||
cmptr->cmsg_type = IP_PKTINFO;
|
||||
dest.sin_addr.s_addr = INADDR_BROADCAST;
|
||||
dest.sin_port = htons(daemon->dhcp_client_port);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* unicast to unconfigured client. Inject mac address direct into ARP cache.
|
||||
struct sockaddr limits size to 14 bytes. */
|
||||
dest.sin_addr = mess->yiaddr;
|
||||
dest.sin_port = htons(daemon->dhcp_client_port);
|
||||
memcpy(&arp_req.arp_pa, &dest, sizeof(struct sockaddr_in));
|
||||
arp_req.arp_ha.sa_family = mess->htype;
|
||||
memcpy(arp_req.arp_ha.sa_data, mess->chaddr, mess->hlen);
|
||||
/* interface name already copied in */
|
||||
arp_req.arp_flags = ATF_COM;
|
||||
ioctl(daemon->dhcpfd, SIOCSARP, &arp_req);
|
||||
cmptr->cmsg_type = IP_PKTINFO;
|
||||
|
||||
if ((ntohs(mess->flags) & 0x8000) || mess->hlen == 0 ||
|
||||
mess->hlen > sizeof(ifr.ifr_addr.sa_data) || mess->htype == 0)
|
||||
{
|
||||
/* broadcast to 255.255.255.255 (or mac address invalid) */
|
||||
dest.sin_addr.s_addr = INADDR_BROADCAST;
|
||||
dest.sin_port = htons(daemon->dhcp_client_port);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* unicast to unconfigured client. Inject mac address direct into ARP cache.
|
||||
struct sockaddr limits size to 14 bytes. */
|
||||
dest.sin_addr = mess->yiaddr;
|
||||
dest.sin_port = htons(daemon->dhcp_client_port);
|
||||
memcpy(&arp_req.arp_pa, &dest, sizeof(struct sockaddr_in));
|
||||
arp_req.arp_ha.sa_family = mess->htype;
|
||||
memcpy(arp_req.arp_ha.sa_data, mess->chaddr, mess->hlen);
|
||||
/* interface name already copied in */
|
||||
arp_req.arp_flags = ATF_COM;
|
||||
if (ioctl(daemon->dhcpfd, SIOCSARP, &arp_req) == -1)
|
||||
my_syslog(MS_DHCP | LOG_ERR, _("ARP-cache injection failed: %s"), strerror(errno));
|
||||
}
|
||||
}
|
||||
#elif defined(HAVE_SOLARIS_NETWORK)
|
||||
else if ((ntohs(mess->flags) & 0x8000) || mess->hlen != ETHER_ADDR_LEN || mess->htype != ARPHRD_ETHER)
|
||||
@@ -442,9 +463,14 @@ void dhcp_packet(time_t now, int pxe_fd)
|
||||
setsockopt(fd, IPPROTO_IP, IP_BOUND_IF, &iface_index, sizeof(iface_index));
|
||||
#endif
|
||||
|
||||
while(sendmsg(fd, &msg, 0) == -1 && retry_send());
|
||||
while(retry_send(sendmsg(fd, &msg, 0)));
|
||||
|
||||
/* This can fail when, eg, iptables DROPS destination 255.255.255.255 */
|
||||
if (errno != 0)
|
||||
my_syslog(MS_DHCP | LOG_WARNING, _("Error sending DHCP packet to %s: %s"),
|
||||
inet_ntoa(dest.sin_addr), strerror(errno));
|
||||
}
|
||||
|
||||
|
||||
/* check against secondary interface addresses */
|
||||
static int check_listen_addrs(struct in_addr local, int if_index, char *label,
|
||||
struct in_addr netmask, struct in_addr broadcast, void *vparam)
|
||||
@@ -479,7 +505,7 @@ static int check_listen_addrs(struct in_addr local, int if_index, char *label,
|
||||
3) Fills in local (this host) and router (this host or relay) addresses.
|
||||
4) Links contexts which are valid for hosts directly connected to the arrival interface on ->current.
|
||||
|
||||
Note that the current chain may be superceded later for configured hosts or those coming via gateways. */
|
||||
Note that the current chain may be superseded later for configured hosts or those coming via gateways. */
|
||||
|
||||
static int complete_context(struct in_addr local, int if_index, char *label,
|
||||
struct in_addr netmask, struct in_addr broadcast, void *vparam)
|
||||
@@ -579,7 +605,7 @@ struct dhcp_context *narrow_context(struct dhcp_context *context,
|
||||
{
|
||||
/* We start of with a set of possible contexts, all on the current physical interface.
|
||||
These are chained on ->current.
|
||||
Here we have an address, and return the actual context correponding to that
|
||||
Here we have an address, and return the actual context corresponding to that
|
||||
address. Note that none may fit, if the address came a dhcp-host and is outside
|
||||
any dhcp-range. In that case we return a static range if possible, or failing that,
|
||||
any context on the correct subnet. (If there's more than one, this is a dodgy
|
||||
@@ -621,9 +647,69 @@ struct dhcp_config *config_find_by_address(struct dhcp_config *configs, struct i
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Check if and address is in use by sending ICMP ping.
|
||||
This wrapper handles a cache and load-limiting.
|
||||
Return is NULL is address in use, or a pointer to a cache entry
|
||||
recording that it isn't. */
|
||||
struct ping_result *do_icmp_ping(time_t now, struct in_addr addr, unsigned int hash, int loopback)
|
||||
{
|
||||
static struct ping_result dummy;
|
||||
struct ping_result *r, *victim = NULL;
|
||||
int count, max = (int)(0.6 * (((float)PING_CACHE_TIME)/
|
||||
((float)PING_WAIT)));
|
||||
|
||||
/* check if we failed to ping addr sometime in the last
|
||||
PING_CACHE_TIME seconds. If so, assume the same situation still exists.
|
||||
This avoids problems when a stupid client bangs
|
||||
on us repeatedly. As a final check, if we did more
|
||||
than 60% of the possible ping checks in the last
|
||||
PING_CACHE_TIME, we are in high-load mode, so don't do any more. */
|
||||
for (count = 0, r = daemon->ping_results; r; r = r->next)
|
||||
if (difftime(now, r->time) > (float)PING_CACHE_TIME)
|
||||
victim = r; /* old record */
|
||||
else
|
||||
{
|
||||
count++;
|
||||
if (r->addr.s_addr == addr.s_addr)
|
||||
return r;
|
||||
}
|
||||
|
||||
/* didn't find cached entry */
|
||||
if ((count >= max) || option_bool(OPT_NO_PING) || loopback)
|
||||
{
|
||||
/* overloaded, or configured not to check, loopback interface, return "not in use" */
|
||||
dummy.hash = hash;
|
||||
return &dummy;
|
||||
}
|
||||
else if (icmp_ping(addr))
|
||||
return NULL; /* address in use. */
|
||||
else
|
||||
{
|
||||
/* at this point victim may hold an expired record */
|
||||
if (!victim)
|
||||
{
|
||||
if ((victim = whine_malloc(sizeof(struct ping_result))))
|
||||
{
|
||||
victim->next = daemon->ping_results;
|
||||
daemon->ping_results = victim;
|
||||
}
|
||||
}
|
||||
|
||||
/* record that this address is OK for 30s
|
||||
without more ping checks */
|
||||
if (victim)
|
||||
{
|
||||
victim->addr = addr;
|
||||
victim->time = now;
|
||||
victim->hash = hash;
|
||||
}
|
||||
return victim;
|
||||
}
|
||||
}
|
||||
|
||||
int address_allocate(struct dhcp_context *context,
|
||||
struct in_addr *addrp, unsigned char *hwaddr, int hw_len,
|
||||
struct dhcp_netid *netids, time_t now)
|
||||
struct dhcp_netid *netids, time_t now, int loopback)
|
||||
{
|
||||
/* Find a free address: exclude anything in use and anything allocated to
|
||||
a particular hwaddr/clientid/hostname in our configuration.
|
||||
@@ -637,7 +723,11 @@ int address_allocate(struct dhcp_context *context,
|
||||
/* hash hwaddr: use the SDBM hashing algorithm. Seems to give good
|
||||
dispersal even with similarly-valued "strings". */
|
||||
for (j = 0, i = 0; i < hw_len; i++)
|
||||
j += hwaddr[i] + (j << 6) + (j << 16) - j;
|
||||
j = hwaddr[i] + (j << 6) + (j << 16) - j;
|
||||
|
||||
/* j == 0 is marker */
|
||||
if (j == 0)
|
||||
j = 1;
|
||||
|
||||
for (pass = 0; pass <= 1; pass++)
|
||||
for (c = context; c; c = c->current)
|
||||
@@ -675,69 +765,27 @@ int address_allocate(struct dhcp_context *context,
|
||||
(!IN_CLASSC(ntohl(addr.s_addr)) ||
|
||||
((ntohl(addr.s_addr) & 0xff) != 0xff && ((ntohl(addr.s_addr) & 0xff) != 0x0))))
|
||||
{
|
||||
struct ping_result *r, *victim = NULL;
|
||||
int count, max = (int)(0.6 * (((float)PING_CACHE_TIME)/
|
||||
((float)PING_WAIT)));
|
||||
struct ping_result *r;
|
||||
|
||||
*addrp = addr;
|
||||
|
||||
/* check if we failed to ping addr sometime in the last
|
||||
PING_CACHE_TIME seconds. If so, assume the same situation still exists.
|
||||
This avoids problems when a stupid client bangs
|
||||
on us repeatedly. As a final check, if we did more
|
||||
than 60% of the possible ping checks in the last
|
||||
PING_CACHE_TIME, we are in high-load mode, so don't do any more. */
|
||||
for (count = 0, r = daemon->ping_results; r; r = r->next)
|
||||
if (difftime(now, r->time) > (float)PING_CACHE_TIME)
|
||||
victim = r; /* old record */
|
||||
else
|
||||
{
|
||||
count++;
|
||||
if (r->addr.s_addr == addr.s_addr)
|
||||
{
|
||||
/* consec-ip mode: we offered this address for another client
|
||||
(different hash) recently, don't offer it to this one. */
|
||||
if (option_bool(OPT_CONSEC_ADDR) && r->hash != j)
|
||||
break;
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!r)
|
||||
{
|
||||
if ((count < max) && !option_bool(OPT_NO_PING) && icmp_ping(addr))
|
||||
if ((r = do_icmp_ping(now, addr, j, loopback)))
|
||||
{
|
||||
/* consec-ip mode: we offered this address for another client
|
||||
(different hash) recently, don't offer it to this one. */
|
||||
if (!option_bool(OPT_CONSEC_ADDR) || r->hash == j)
|
||||
{
|
||||
/* address in use: perturb address selection so that we are
|
||||
less likely to try this address again. */
|
||||
if (!option_bool(OPT_CONSEC_ADDR))
|
||||
c->addr_epoch++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* at this point victim may hold an expired record */
|
||||
if (!victim)
|
||||
{
|
||||
if ((victim = whine_malloc(sizeof(struct ping_result))))
|
||||
{
|
||||
victim->next = daemon->ping_results;
|
||||
daemon->ping_results = victim;
|
||||
}
|
||||
}
|
||||
|
||||
/* record that this address is OK for 30s
|
||||
without more ping checks */
|
||||
if (victim)
|
||||
{
|
||||
victim->addr = addr;
|
||||
victim->time = now;
|
||||
victim->hash = j;
|
||||
}
|
||||
*addrp = addr;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* address in use: perturb address selection so that we are
|
||||
less likely to try this address again. */
|
||||
if (!option_bool(OPT_CONSEC_ADDR))
|
||||
c->addr_epoch++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
addr.s_addr = htonl(ntohl(addr.s_addr) + 1);
|
||||
|
||||
if (addr.s_addr == htonl(ntohl(c->end.s_addr) + 1))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2014 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2018 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
|
||||
|
||||
170
src/dhcp6.c
170
src/dhcp6.c
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2014 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2018 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
|
||||
@@ -27,17 +27,10 @@ struct iface_param {
|
||||
int ind, addr_match;
|
||||
};
|
||||
|
||||
struct mac_param {
|
||||
struct in6_addr *target;
|
||||
unsigned char *mac;
|
||||
unsigned int maclen;
|
||||
};
|
||||
|
||||
|
||||
static int complete_context6(struct in6_addr *local, int prefix,
|
||||
int scope, int if_index, int flags,
|
||||
unsigned int preferred, unsigned int valid, void *vparam);
|
||||
static int find_mac(int family, char *addrp, char *mac, size_t maclen, void *parmv);
|
||||
static int make_duid1(int index, unsigned int type, char *mac, size_t maclen, void *parm);
|
||||
|
||||
void dhcp6_init(void)
|
||||
@@ -58,9 +51,9 @@ void dhcp6_init(void)
|
||||
!set_ipv6pktinfo(fd))
|
||||
die (_("cannot create DHCPv6 socket: %s"), NULL, EC_BADNET);
|
||||
|
||||
/* When bind-interfaces is set, there might be more than one dnmsasq
|
||||
/* When bind-interfaces is set, there might be more than one dnsmasq
|
||||
instance binding port 547. That's OK if they serve different networks.
|
||||
Need to set REUSEADDR|REUSEPORT to make this posible.
|
||||
Need to set REUSEADDR|REUSEPORT to make this possible.
|
||||
Handle the case that REUSEPORT is defined, but the kernel doesn't
|
||||
support it. This handles the introduction of REUSEPORT on Linux. */
|
||||
if (option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND))
|
||||
@@ -144,6 +137,8 @@ void dhcp6_packet(time_t now)
|
||||
|
||||
if ((port = relay_reply6(&from, sz, ifr.ifr_name)) == 0)
|
||||
{
|
||||
struct dhcp_bridge *bridge, *alias;
|
||||
|
||||
for (tmp = daemon->if_except; tmp; tmp = tmp->next)
|
||||
if (tmp->name && wildcard_match(tmp->name, ifr.ifr_name))
|
||||
return;
|
||||
@@ -160,6 +155,30 @@ void dhcp6_packet(time_t now)
|
||||
memset(&parm.fallback, 0, IN6ADDRSZ);
|
||||
memset(&parm.ll_addr, 0, IN6ADDRSZ);
|
||||
memset(&parm.ula_addr, 0, IN6ADDRSZ);
|
||||
|
||||
/* If the interface on which the DHCPv6 request was received is
|
||||
an alias of some other interface (as specified by the
|
||||
--bridge-interface option), change parm.ind so that we look
|
||||
for DHCPv6 contexts associated with the aliased interface
|
||||
instead of with the aliasing one. */
|
||||
for (bridge = daemon->bridges; bridge; bridge = bridge->next)
|
||||
{
|
||||
for (alias = bridge->alias; alias; alias = alias->next)
|
||||
if (wildcard_matchn(alias->iface, ifr.ifr_name, IF_NAMESIZE))
|
||||
{
|
||||
parm.ind = if_nametoindex(bridge->iface);
|
||||
if (!parm.ind)
|
||||
{
|
||||
my_syslog(MS_DHCP | LOG_WARNING,
|
||||
_("unknown interface %s in bridge-interface"),
|
||||
bridge->iface);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (alias)
|
||||
break;
|
||||
}
|
||||
|
||||
for (context = daemon->dhcp6; context; context = context->next)
|
||||
if (IN6_IS_ADDR_UNSPECIFIED(&context->start6) && context->prefix == 0)
|
||||
@@ -201,14 +220,14 @@ void dhcp6_packet(time_t now)
|
||||
inet_pton(AF_INET6, ALL_SERVERS, &all_servers);
|
||||
|
||||
if (!IN6_ARE_ADDR_EQUAL(&dst_addr, &all_servers))
|
||||
relay_upstream6(parm.relay, sz, &from.sin6_addr, from.sin6_scope_id);
|
||||
relay_upstream6(parm.relay, sz, &from.sin6_addr, from.sin6_scope_id, now);
|
||||
return;
|
||||
}
|
||||
|
||||
/* May have configured relay, but not DHCP server */
|
||||
if (!daemon->doing_dhcp6)
|
||||
return;
|
||||
|
||||
|
||||
lease_prune(NULL, now); /* lose any expired leases */
|
||||
|
||||
port = dhcp6_reply(parm.current, if_index, ifr.ifr_name, &parm.fallback,
|
||||
@@ -225,79 +244,56 @@ void dhcp6_packet(time_t now)
|
||||
if (port != 0)
|
||||
{
|
||||
from.sin6_port = htons(port);
|
||||
while (sendto(daemon->dhcp6fd, daemon->outpacket.iov_base, save_counter(0),
|
||||
0, (struct sockaddr *)&from, sizeof(from)) == -1 &&
|
||||
retry_send());
|
||||
while (retry_send(sendto(daemon->dhcp6fd, daemon->outpacket.iov_base,
|
||||
save_counter(0), 0, (struct sockaddr *)&from,
|
||||
sizeof(from))));
|
||||
}
|
||||
}
|
||||
|
||||
void get_client_mac(struct in6_addr *client, int iface, unsigned char *mac, unsigned int *maclenp, unsigned int *mactypep)
|
||||
void get_client_mac(struct in6_addr *client, int iface, unsigned char *mac, unsigned int *maclenp, unsigned int *mactypep, time_t now)
|
||||
{
|
||||
/* Recieving a packet from a host does not populate the neighbour
|
||||
/* Receiving a packet from a host does not populate the neighbour
|
||||
cache, so we send a neighbour discovery request if we can't
|
||||
find the sender. Repeat a few times in case of packet loss. */
|
||||
|
||||
struct neigh_packet neigh;
|
||||
struct sockaddr_in6 addr;
|
||||
struct mac_param mac_param;
|
||||
int i;
|
||||
union mysockaddr addr;
|
||||
int i, maclen;
|
||||
|
||||
neigh.type = ND_NEIGHBOR_SOLICIT;
|
||||
neigh.code = 0;
|
||||
neigh.reserved = 0;
|
||||
neigh.target = *client;
|
||||
|
||||
/* RFC4443 section-2.3: checksum has to be zero to be calculated */
|
||||
neigh.checksum = 0;
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
#ifdef HAVE_SOCKADDR_SA_LEN
|
||||
addr.sin6_len = sizeof(struct sockaddr_in6);
|
||||
addr.in6.sin6_len = sizeof(struct sockaddr_in6);
|
||||
#endif
|
||||
addr.sin6_family = AF_INET6;
|
||||
addr.sin6_port = htons(IPPROTO_ICMPV6);
|
||||
addr.sin6_addr = *client;
|
||||
addr.sin6_scope_id = iface;
|
||||
|
||||
mac_param.target = client;
|
||||
mac_param.maclen = 0;
|
||||
mac_param.mac = mac;
|
||||
addr.in6.sin6_family = AF_INET6;
|
||||
addr.in6.sin6_port = htons(IPPROTO_ICMPV6);
|
||||
addr.in6.sin6_addr = *client;
|
||||
addr.in6.sin6_scope_id = iface;
|
||||
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
struct timespec ts;
|
||||
|
||||
iface_enumerate(AF_UNSPEC, &mac_param, find_mac);
|
||||
|
||||
if (mac_param.maclen != 0)
|
||||
if ((maclen = find_mac(&addr, mac, 0, now)) != 0)
|
||||
break;
|
||||
|
||||
sendto(daemon->icmp6fd, &neigh, sizeof(neigh), 0, (struct sockaddr *)&addr, sizeof(addr));
|
||||
|
||||
sendto(daemon->icmp6fd, &neigh, sizeof(neigh), 0, &addr.sa, sizeof(addr));
|
||||
|
||||
ts.tv_sec = 0;
|
||||
ts.tv_nsec = 100000000; /* 100ms */
|
||||
nanosleep(&ts, NULL);
|
||||
}
|
||||
|
||||
*maclenp = mac_param.maclen;
|
||||
*maclenp = maclen;
|
||||
*mactypep = ARPHRD_ETHER;
|
||||
}
|
||||
|
||||
static int find_mac(int family, char *addrp, char *mac, size_t maclen, void *parmv)
|
||||
{
|
||||
struct mac_param *parm = parmv;
|
||||
|
||||
if (family == AF_INET6 && IN6_ARE_ADDR_EQUAL(parm->target, (struct in6_addr *)addrp))
|
||||
{
|
||||
if (maclen <= DHCP_CHADDR_MAX)
|
||||
{
|
||||
parm->maclen = maclen;
|
||||
memcpy(parm->mac, mac, maclen);
|
||||
}
|
||||
|
||||
return 0; /* found, abort */
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int complete_context6(struct in6_addr *local, int prefix,
|
||||
int scope, int if_index, int flags, unsigned int preferred,
|
||||
unsigned int valid, void *vparam)
|
||||
@@ -348,7 +344,7 @@ static int complete_context6(struct in6_addr *local, int prefix,
|
||||
{
|
||||
struct dhcp_context *tmp, **up;
|
||||
|
||||
/* use interface values only for contructed contexts */
|
||||
/* use interface values only for constructed contexts */
|
||||
if (!(context->flags & CONTEXT_CONSTRUCTED))
|
||||
preferred = valid = 0xffffffff;
|
||||
else if (flags & IFACE_DEPRECATED)
|
||||
@@ -424,7 +420,7 @@ struct dhcp_context *address6_allocate(struct dhcp_context *context, unsigned c
|
||||
j = rand64();
|
||||
else
|
||||
for (j = iaid, i = 0; i < clid_len; i++)
|
||||
j += clid[i] + (j << 6) + (j << 16) - j;
|
||||
j = clid[i] + (j << 6) + (j << 16) - j;
|
||||
|
||||
for (pass = 0; pass <= plain_range ? 1 : 0; pass++)
|
||||
for (c = context; c; c = c->current)
|
||||
@@ -438,7 +434,16 @@ struct dhcp_context *address6_allocate(struct dhcp_context *context, unsigned c
|
||||
/* seed is largest extant lease addr in this context */
|
||||
start = lease_find_max_addr6(c) + serial;
|
||||
else
|
||||
start = addr6part(&c->start6) + ((j + c->addr_epoch) % (1 + addr6part(&c->end6) - addr6part(&c->start6)));
|
||||
{
|
||||
u64 range = 1 + addr6part(&c->end6) - addr6part(&c->start6);
|
||||
u64 offset = j + c->addr_epoch;
|
||||
|
||||
/* don't divide by zero if range is whole 2^64 */
|
||||
if (range != 0)
|
||||
offset = offset % range;
|
||||
|
||||
start = addr6part(&c->start6) + offset;
|
||||
}
|
||||
|
||||
/* iterate until we find a free address. */
|
||||
addr = start;
|
||||
@@ -635,13 +640,20 @@ static int construct_worker(struct in6_addr *local, int prefix,
|
||||
return 0;
|
||||
|
||||
for (template = daemon->dhcp6; template; template = template->next)
|
||||
if (!(template->flags & CONTEXT_TEMPLATE))
|
||||
if (!(template->flags & (CONTEXT_TEMPLATE | CONTEXT_CONSTRUCTED)))
|
||||
{
|
||||
/* non-template entries, just fill in interface and local addresses */
|
||||
if (prefix <= template->prefix &&
|
||||
is_same_net6(local, &template->start6, template->prefix) &&
|
||||
is_same_net6(local, &template->end6, template->prefix))
|
||||
{
|
||||
/* First time found, do fast RA. */
|
||||
if (template->if_index != if_index || !IN6_ARE_ADDR_EQUAL(&template->local6, local))
|
||||
{
|
||||
ra_start_unsolicited(param->now, template);
|
||||
param->newone = 1;
|
||||
}
|
||||
|
||||
template->if_index = if_index;
|
||||
template->local6 = *local;
|
||||
}
|
||||
@@ -656,24 +668,33 @@ static int construct_worker(struct in6_addr *local, int prefix,
|
||||
setaddr6part(&end6, addr6part(&template->end6));
|
||||
|
||||
for (context = daemon->dhcp6; context; context = context->next)
|
||||
if ((context->flags & CONTEXT_CONSTRUCTED) &&
|
||||
if (!(context->flags & CONTEXT_TEMPLATE) &&
|
||||
IN6_ARE_ADDR_EQUAL(&start6, &context->start6) &&
|
||||
IN6_ARE_ADDR_EQUAL(&end6, &context->end6))
|
||||
{
|
||||
int flags = context->flags;
|
||||
context->flags &= ~(CONTEXT_GC | CONTEXT_OLD);
|
||||
if (flags & CONTEXT_OLD)
|
||||
/* If there's an absolute address context covering this address
|
||||
then don't construct one as well. */
|
||||
if (!(context->flags & CONTEXT_CONSTRUCTED))
|
||||
break;
|
||||
|
||||
if (context->if_index == if_index)
|
||||
{
|
||||
/* address went, now it's back */
|
||||
log_context(AF_INET6, context);
|
||||
/* fast RAs for a while */
|
||||
ra_start_unsolicted(param->now, context);
|
||||
param->newone = 1;
|
||||
/* Add address to name again */
|
||||
if (context->flags & CONTEXT_RA_NAME)
|
||||
param->newname = 1;
|
||||
int cflags = context->flags;
|
||||
context->flags &= ~(CONTEXT_GC | CONTEXT_OLD);
|
||||
if (cflags & CONTEXT_OLD)
|
||||
{
|
||||
/* address went, now it's back, and on the same interface */
|
||||
log_context(AF_INET6, context);
|
||||
/* fast RAs for a while */
|
||||
ra_start_unsolicited(param->now, context);
|
||||
param->newone = 1;
|
||||
/* Add address to name again */
|
||||
if (context->flags & CONTEXT_RA_NAME)
|
||||
param->newname = 1;
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!context && (context = whine_malloc(sizeof (struct dhcp_context))))
|
||||
@@ -690,7 +711,7 @@ static int construct_worker(struct in6_addr *local, int prefix,
|
||||
context->next = daemon->dhcp6;
|
||||
daemon->dhcp6 = context;
|
||||
|
||||
ra_start_unsolicted(param->now, context);
|
||||
ra_start_unsolicited(param->now, context);
|
||||
/* we created a new one, need to call
|
||||
lease_update_file to get periodic functions called */
|
||||
param->newone = 1;
|
||||
@@ -727,8 +748,7 @@ void dhcp_construct_contexts(time_t now)
|
||||
|
||||
if (context->flags & CONTEXT_GC && !(context->flags & CONTEXT_OLD))
|
||||
{
|
||||
if ((context->flags & (CONTEXT_RA_ONLY | CONTEXT_RA_NAME | CONTEXT_RA_STATELESS)) ||
|
||||
option_bool(OPT_RA))
|
||||
if ((context->flags & CONTEXT_RA) || option_bool(OPT_RA))
|
||||
{
|
||||
/* previously constructed context has gone. advertise it's demise */
|
||||
context->flags |= CONTEXT_OLD;
|
||||
@@ -739,7 +759,7 @@ void dhcp_construct_contexts(time_t now)
|
||||
/* maximum time is 2 hours, from RFC */
|
||||
if (context->saved_valid > 7200) /* 2 hours */
|
||||
context->saved_valid = 7200;
|
||||
ra_start_unsolicted(now, context);
|
||||
ra_start_unsolicited(now, context);
|
||||
param.newone = 1; /* include deletion */
|
||||
|
||||
if (context->flags & CONTEXT_RA_NAME)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2014 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2018 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
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
#define NAMESERVER_PORT 53
|
||||
#define TFTP_PORT 69
|
||||
#define MIN_PORT 1024 /* first non-reserved port */
|
||||
#define MAX_PORT 65535u
|
||||
|
||||
#define IN6ADDRSZ 16
|
||||
#define INADDRSZ 4
|
||||
@@ -68,6 +70,7 @@
|
||||
#define T_RRSIG 46
|
||||
#define T_NSEC 47
|
||||
#define T_DNSKEY 48
|
||||
#define T_NSEC3 50
|
||||
#define T_TKEY 249
|
||||
#define T_TSIG 250
|
||||
#define T_AXFR 252
|
||||
@@ -76,6 +79,8 @@
|
||||
|
||||
#define EDNS0_OPTION_MAC 65001 /* dyndns.org temporary assignment */
|
||||
#define EDNS0_OPTION_CLIENT_SUBNET 8 /* IANA */
|
||||
#define EDNS0_OPTION_NOMDEVICEID 65073 /* Nominum temporary assignment */
|
||||
#define EDNS0_OPTION_NOMCPEID 65074 /* Nominum temporary assignment */
|
||||
|
||||
struct dns_header {
|
||||
u16 id;
|
||||
@@ -83,15 +88,15 @@ struct dns_header {
|
||||
u16 qdcount,ancount,nscount,arcount;
|
||||
};
|
||||
|
||||
#define HB3_QR 0x80
|
||||
#define HB3_QR 0x80 /* Query */
|
||||
#define HB3_OPCODE 0x78
|
||||
#define HB3_AA 0x04
|
||||
#define HB3_TC 0x02
|
||||
#define HB3_RD 0x01
|
||||
#define HB3_AA 0x04 /* Authoritative Answer */
|
||||
#define HB3_TC 0x02 /* TrunCated */
|
||||
#define HB3_RD 0x01 /* Recursion Desired */
|
||||
|
||||
#define HB4_RA 0x80
|
||||
#define HB4_AD 0x20
|
||||
#define HB4_CD 0x10
|
||||
#define HB4_RA 0x80 /* Recursion Available */
|
||||
#define HB4_AD 0x20 /* Authenticated Data */
|
||||
#define HB4_CD 0x10 /* Checking Disabled */
|
||||
#define HB4_RCODE 0x0f
|
||||
|
||||
#define OPCODE(x) (((x)->hb3 & HB3_OPCODE) >> 3)
|
||||
@@ -141,3 +146,11 @@ struct dns_header {
|
||||
|
||||
#define ADD_RDLEN(header, pp, plen, len) \
|
||||
(!CHECK_LEN(header, pp, plen, len) ? 0 : (((pp) += (len)), 1))
|
||||
|
||||
/* Escape character in our presentation format for names.
|
||||
Cannot be '.' or /000 and must be !isprint().
|
||||
Note that escaped chars are stored as
|
||||
<NAME_ESCAPE> <orig-char+1>
|
||||
to ensure that the escaped form of /000 doesn't include /000
|
||||
*/
|
||||
#define NAME_ESCAPE 1
|
||||
|
||||
747
src/dnsmasq.c
747
src/dnsmasq.c
File diff suppressed because it is too large
Load Diff
457
src/dnsmasq.h
457
src/dnsmasq.h
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2014 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2018 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
|
||||
@@ -14,7 +14,13 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define COPYRIGHT "Copyright (c) 2000-2014 Simon Kelley"
|
||||
#define COPYRIGHT "Copyright (c) 2000-2018 Simon Kelley"
|
||||
|
||||
/* We do defines that influence behavior of stdio.h, so complain
|
||||
if included too early. */
|
||||
#ifdef _STDIO_H
|
||||
# error "Header file stdio.h included too early!"
|
||||
#endif
|
||||
|
||||
#ifndef NO_LARGEFILE
|
||||
/* Ensure we can use files >2GB (log files may grow this big) */
|
||||
@@ -82,7 +88,7 @@ typedef unsigned long long u64;
|
||||
#if defined(HAVE_SOLARIS_NETWORK)
|
||||
# include <sys/sockio.h>
|
||||
#endif
|
||||
#include <sys/select.h>
|
||||
#include <sys/poll.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/un.h>
|
||||
@@ -113,6 +119,9 @@ typedef unsigned long long u64;
|
||||
#include <net/if_arp.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
#ifdef HAVE_IPV6
|
||||
#include <netinet/ip6.h>
|
||||
#endif
|
||||
#include <netinet/ip_icmp.h>
|
||||
#include <sys/uio.h>
|
||||
#include <syslog.h>
|
||||
@@ -124,7 +133,7 @@ typedef unsigned long long u64;
|
||||
#if defined(HAVE_LINUX_NETWORK)
|
||||
#include <linux/capability.h>
|
||||
/* There doesn't seem to be a universally-available
|
||||
userpace header for these. */
|
||||
userspace header for these. */
|
||||
extern int capset(cap_user_header_t header, cap_user_data_t data);
|
||||
extern int capget(cap_user_header_t header, cap_user_data_t data);
|
||||
#define LINUX_CAPABILITY_VERSION_1 0x19980330
|
||||
@@ -136,6 +145,10 @@ extern int capget(cap_user_header_t header, cap_user_data_t data);
|
||||
#include <priv.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DNSSEC
|
||||
# include <nettle/nettle-meta.h>
|
||||
#endif
|
||||
|
||||
/* daemon is function in the C library.... */
|
||||
#define daemon dnsmasq_daemon
|
||||
|
||||
@@ -144,26 +157,32 @@ struct event_desc {
|
||||
int event, data, msg_sz;
|
||||
};
|
||||
|
||||
#define EVENT_RELOAD 1
|
||||
#define EVENT_DUMP 2
|
||||
#define EVENT_ALARM 3
|
||||
#define EVENT_TERM 4
|
||||
#define EVENT_CHILD 5
|
||||
#define EVENT_REOPEN 6
|
||||
#define EVENT_EXITED 7
|
||||
#define EVENT_KILLED 8
|
||||
#define EVENT_EXEC_ERR 9
|
||||
#define EVENT_PIPE_ERR 10
|
||||
#define EVENT_USER_ERR 11
|
||||
#define EVENT_CAP_ERR 12
|
||||
#define EVENT_PIDFILE 13
|
||||
#define EVENT_HUSER_ERR 14
|
||||
#define EVENT_GROUP_ERR 15
|
||||
#define EVENT_DIE 16
|
||||
#define EVENT_LOG_ERR 17
|
||||
#define EVENT_FORK_ERR 18
|
||||
#define EVENT_LUA_ERR 19
|
||||
#define EVENT_TFTP_ERR 20
|
||||
#define EVENT_RELOAD 1
|
||||
#define EVENT_DUMP 2
|
||||
#define EVENT_ALARM 3
|
||||
#define EVENT_TERM 4
|
||||
#define EVENT_CHILD 5
|
||||
#define EVENT_REOPEN 6
|
||||
#define EVENT_EXITED 7
|
||||
#define EVENT_KILLED 8
|
||||
#define EVENT_EXEC_ERR 9
|
||||
#define EVENT_PIPE_ERR 10
|
||||
#define EVENT_USER_ERR 11
|
||||
#define EVENT_CAP_ERR 12
|
||||
#define EVENT_PIDFILE 13
|
||||
#define EVENT_HUSER_ERR 14
|
||||
#define EVENT_GROUP_ERR 15
|
||||
#define EVENT_DIE 16
|
||||
#define EVENT_LOG_ERR 17
|
||||
#define EVENT_FORK_ERR 18
|
||||
#define EVENT_LUA_ERR 19
|
||||
#define EVENT_TFTP_ERR 20
|
||||
#define EVENT_INIT 21
|
||||
#define EVENT_NEWADDR 22
|
||||
#define EVENT_NEWROUTE 23
|
||||
#define EVENT_TIME_ERR 24
|
||||
#define EVENT_SCRIPT_LOG 25
|
||||
#define EVENT_TIME 26
|
||||
|
||||
/* Exit codes. */
|
||||
#define EC_GOOD 0
|
||||
@@ -174,13 +193,6 @@ struct event_desc {
|
||||
#define EC_MISC 5
|
||||
#define EC_INIT_OFFSET 10
|
||||
|
||||
/* Min buffer size: we check after adding each record, so there must be
|
||||
memory for the largest packet, and the largest record so the
|
||||
min for DNS is PACKETSZ+MAXDNAME+RRFIXEDSZ which is < 1000.
|
||||
This might be increased is EDNS packet size if greater than the minimum.
|
||||
*/
|
||||
#define DNSMASQ_PACKETSZ PACKETSZ+MAXDNAME+RRFIXEDSZ
|
||||
|
||||
/* Trust the compiler dead-code eliminator.... */
|
||||
#define option_bool(x) (((x) < 32) ? daemon->options & (1u << (x)) : daemon->options2 & (1u << ((x) - 32)))
|
||||
|
||||
@@ -213,7 +225,7 @@ struct event_desc {
|
||||
#define OPT_TFTP_SECURE 26
|
||||
#define OPT_TFTP_NOBLOCK 27
|
||||
#define OPT_LOG_OPTS 28
|
||||
#define OPT_TFTP_APREF 29
|
||||
#define OPT_TFTP_APREF_IP 29
|
||||
#define OPT_NO_OVERRIDE 30
|
||||
#define OPT_NO_REBIND 31
|
||||
#define OPT_ADD_MAC 32
|
||||
@@ -230,14 +242,25 @@ struct event_desc {
|
||||
#define OPT_QUIET_DHCP6 43
|
||||
#define OPT_QUIET_RA 44
|
||||
#define OPT_DNSSEC_VALID 45
|
||||
#define OPT_DNSSEC_PERMISS 46
|
||||
#define OPT_DNSSEC_TIME 46
|
||||
#define OPT_DNSSEC_DEBUG 47
|
||||
#define OPT_LAST 48
|
||||
#define OPT_DNSSEC_IGN_NS 48
|
||||
#define OPT_LOCAL_SERVICE 49
|
||||
#define OPT_LOOP_DETECT 50
|
||||
#define OPT_EXTRALOG 51
|
||||
#define OPT_TFTP_NO_FAIL 52
|
||||
#define OPT_SCRIPT_ARP 53
|
||||
#define OPT_MAC_B64 54
|
||||
#define OPT_MAC_HEX 55
|
||||
#define OPT_TFTP_APREF_MAC 56
|
||||
#define OPT_RAPID_COMMIT 57
|
||||
#define OPT_LAST 58
|
||||
|
||||
/* extra flags for my_syslog, we use a couple of facilities since they are known
|
||||
not to occupy the same bits as priorities, no matter how syslog.h is set up. */
|
||||
#define MS_TFTP LOG_USER
|
||||
#define MS_DHCP LOG_DAEMON
|
||||
#define MS_TFTP LOG_USER
|
||||
#define MS_DHCP LOG_DAEMON
|
||||
#define MS_SCRIPT LOG_MAIL
|
||||
|
||||
struct all_addr {
|
||||
union {
|
||||
@@ -246,8 +269,14 @@ struct all_addr {
|
||||
struct in6_addr addr6;
|
||||
#endif
|
||||
/* for log_query */
|
||||
unsigned int keytag;
|
||||
/* for cache_insert if RRSIG, DNSKEY, DS */
|
||||
struct {
|
||||
unsigned short keytag, algo, digest;
|
||||
} log;
|
||||
/* for log_query */
|
||||
struct {
|
||||
unsigned int rcode;
|
||||
} rcode;
|
||||
/* for cache_insert of DNSKEY, DS */
|
||||
struct {
|
||||
unsigned short class, type;
|
||||
} dnssec;
|
||||
@@ -278,10 +307,21 @@ struct naptr {
|
||||
struct naptr *next;
|
||||
};
|
||||
|
||||
#ifndef NO_ID
|
||||
#define TXT_STAT_CACHESIZE 1
|
||||
#define TXT_STAT_INSERTS 2
|
||||
#define TXT_STAT_EVICTIONS 3
|
||||
#define TXT_STAT_MISSES 4
|
||||
#define TXT_STAT_HITS 5
|
||||
#define TXT_STAT_AUTH 6
|
||||
#define TXT_STAT_SERVERS 7
|
||||
#endif
|
||||
|
||||
struct txt_record {
|
||||
char *name;
|
||||
unsigned char *txt;
|
||||
unsigned short class, len;
|
||||
int stat;
|
||||
struct txt_record *next;
|
||||
};
|
||||
|
||||
@@ -291,18 +331,20 @@ struct ptr_record {
|
||||
};
|
||||
|
||||
struct cname {
|
||||
int ttl, flag;
|
||||
char *alias, *target;
|
||||
struct cname *next;
|
||||
struct cname *next, *targetp;
|
||||
};
|
||||
|
||||
struct dnskey {
|
||||
char *name, *key;
|
||||
int keylen, class, algo, flags;
|
||||
struct dnskey *next;
|
||||
struct ds_config {
|
||||
char *name, *digest;
|
||||
int digestlen, class, algo, keytag, digest_type;
|
||||
struct ds_config *next;
|
||||
};
|
||||
|
||||
#define ADDRLIST_LITERAL 1
|
||||
#define ADDRLIST_IPV6 2
|
||||
#define ADDRLIST_REVONLY 4
|
||||
|
||||
struct addrlist {
|
||||
struct all_addr addr;
|
||||
@@ -321,11 +363,13 @@ struct auth_zone {
|
||||
struct auth_name_list *next;
|
||||
} *interface_names;
|
||||
struct addrlist *subnet;
|
||||
struct addrlist *exclude;
|
||||
struct auth_zone *next;
|
||||
};
|
||||
|
||||
|
||||
struct host_record {
|
||||
int ttl;
|
||||
struct name_list {
|
||||
char *name;
|
||||
struct name_list *next;
|
||||
@@ -365,7 +409,7 @@ struct crec {
|
||||
struct crec *cache;
|
||||
struct interface_name *int_name;
|
||||
} target;
|
||||
int uid; /* -1 if union is interface-name */
|
||||
unsigned int uid; /* 0 if union is interface-name */
|
||||
} cname;
|
||||
struct {
|
||||
struct blockdata *keydata;
|
||||
@@ -378,15 +422,10 @@ struct crec {
|
||||
unsigned char algo;
|
||||
unsigned char digest;
|
||||
} ds;
|
||||
struct {
|
||||
struct blockdata *keydata;
|
||||
unsigned short keylen, type_covered, keytag;
|
||||
char algo;
|
||||
} sig;
|
||||
} addr;
|
||||
time_t ttd; /* time to die */
|
||||
/* used as class if DNSKEY/DS/RRSIG, index to source for F_HOSTS */
|
||||
int uid;
|
||||
/* used as class if DNSKEY/DS, index to source for F_HOSTS */
|
||||
unsigned int uid;
|
||||
unsigned short flags;
|
||||
union {
|
||||
char sname[SMALLDNAME];
|
||||
@@ -424,6 +463,20 @@ struct crec {
|
||||
#define F_KEYTAG (1u<<23)
|
||||
#define F_SECSTAT (1u<<24)
|
||||
#define F_NO_RR (1u<<25)
|
||||
#define F_IPSET (1u<<26)
|
||||
#define F_NOEXTRA (1u<<27)
|
||||
#define F_SERVFAIL (1u<<28)
|
||||
#define F_RCODE (1u<<29)
|
||||
|
||||
#define UID_NONE 0
|
||||
/* Values of uid in crecs with F_CONFIG bit set. */
|
||||
/* cname to uid SRC_INTERFACE are to interface names,
|
||||
so use UID_NONE for that to eliminate clashes with
|
||||
any other uid */
|
||||
#define SRC_INTERFACE UID_NONE
|
||||
#define SRC_CONFIG 1
|
||||
#define SRC_HOSTS 2
|
||||
#define SRC_AH 3
|
||||
|
||||
|
||||
/* struct sockaddr is not large enough to hold any address,
|
||||
@@ -456,11 +509,16 @@ union mysockaddr {
|
||||
#define SERV_COUNTED 512 /* workspace for log code */
|
||||
#define SERV_USE_RESOLV 1024 /* forward this domain in the normal way */
|
||||
#define SERV_NO_REBIND 2048 /* inhibit dns-rebind protection */
|
||||
#define SERV_FROM_FILE 4096 /* read from --servers-file */
|
||||
#define SERV_LOOP 8192 /* server causes forwarding loop */
|
||||
#define SERV_DO_DNSSEC 16384 /* Validate DNSSEC when using this server */
|
||||
#define SERV_GOT_TCP 32768 /* Got some data from the TCP connection */
|
||||
|
||||
struct serverfd {
|
||||
int fd;
|
||||
union mysockaddr source_addr;
|
||||
char interface[IF_NAMESIZE+1];
|
||||
unsigned int ifindex, used, preallocated;
|
||||
struct serverfd *next;
|
||||
};
|
||||
|
||||
@@ -474,8 +532,12 @@ struct server {
|
||||
char interface[IF_NAMESIZE+1];
|
||||
struct serverfd *sfd;
|
||||
char *domain; /* set if this server only handles a domain. */
|
||||
int flags, tcpfd;
|
||||
int flags, tcpfd, edns_pktsz;
|
||||
time_t pktsz_reduced;
|
||||
unsigned int queries, failed_queries;
|
||||
#ifdef HAVE_LOOP
|
||||
u32 uid;
|
||||
#endif
|
||||
struct server *next;
|
||||
};
|
||||
|
||||
@@ -488,7 +550,7 @@ struct ipsets {
|
||||
struct irec {
|
||||
union mysockaddr addr;
|
||||
struct in_addr netmask; /* only valid for IPv4 */
|
||||
int tftp_ok, dhcp_ok, mtu, done, warned, dad, dns_auth, index, multicast_done, found;
|
||||
int tftp_ok, dhcp_ok, mtu, done, warned, dad, dns_auth, index, multicast_done, found, label;
|
||||
char *name;
|
||||
struct irec *next;
|
||||
};
|
||||
@@ -507,24 +569,52 @@ struct iname {
|
||||
struct iname *next;
|
||||
};
|
||||
|
||||
/* subnet parameters from command line */
|
||||
struct mysubnet {
|
||||
union mysockaddr addr;
|
||||
int addr_used;
|
||||
int mask;
|
||||
};
|
||||
|
||||
/* resolv-file parms from command-line */
|
||||
struct resolvc {
|
||||
struct resolvc *next;
|
||||
int is_default, logged;
|
||||
time_t mtime;
|
||||
char *name;
|
||||
#ifdef HAVE_INOTIFY
|
||||
int wd; /* inotify watch descriptor */
|
||||
char *file; /* pointer to file part if path */
|
||||
#endif
|
||||
};
|
||||
|
||||
/* adn-hosts parms from command-line (also dhcp-hostsfile and dhcp-optsfile */
|
||||
/* adn-hosts parms from command-line (also dhcp-hostsfile and dhcp-optsfile and dhcp-hostsdir*/
|
||||
#define AH_DIR 1
|
||||
#define AH_INACTIVE 2
|
||||
#define AH_WD_DONE 4
|
||||
#define AH_HOSTS 8
|
||||
#define AH_DHCP_HST 16
|
||||
#define AH_DHCP_OPT 32
|
||||
struct hostsfile {
|
||||
struct hostsfile *next;
|
||||
int flags;
|
||||
char *fname;
|
||||
int index; /* matches to cache entries for logging */
|
||||
#ifdef HAVE_INOTIFY
|
||||
int wd; /* inotify watch descriptor */
|
||||
#endif
|
||||
unsigned int index; /* matches to cache entries for logging */
|
||||
};
|
||||
|
||||
/* packet-dump flags */
|
||||
#define DUMP_QUERY 0x0001
|
||||
#define DUMP_REPLY 0x0002
|
||||
#define DUMP_UP_QUERY 0x0004
|
||||
#define DUMP_UP_REPLY 0x0008
|
||||
#define DUMP_SEC_QUERY 0x0010
|
||||
#define DUMP_SEC_REPLY 0x0020
|
||||
#define DUMP_BOGUS 0x0040
|
||||
#define DUMP_SEC_BOGUS 0x0080
|
||||
|
||||
|
||||
/* DNSSEC status values. */
|
||||
#define STAT_SECURE 1
|
||||
@@ -533,12 +623,20 @@ struct hostsfile {
|
||||
#define STAT_NEED_DS 4
|
||||
#define STAT_NEED_KEY 5
|
||||
#define STAT_TRUNCATED 6
|
||||
#define STAT_SECURE_WILDCARD 7
|
||||
#define STAT_OK 8
|
||||
#define STAT_ABANDONED 9
|
||||
|
||||
#define FREC_NOREBIND 1
|
||||
#define FREC_CHECKING_DISABLED 2
|
||||
#define FREC_HAS_SUBNET 4
|
||||
#define FREC_DNSKEY_QUERY 8
|
||||
#define FREC_DS_QUERY 16
|
||||
#define FREC_AD_QUESTION 32
|
||||
#define FREC_DO_QUESTION 64
|
||||
#define FREC_ADDED_PHEADER 128
|
||||
#define FREC_TEST_PKTSZ 256
|
||||
#define FREC_HAS_EXTRADATA 512
|
||||
|
||||
#ifdef HAVE_DNSSEC
|
||||
#define HASH_SIZE 20 /* SHA-1 digest size */
|
||||
@@ -556,11 +654,11 @@ struct frec {
|
||||
#endif
|
||||
unsigned int iface;
|
||||
unsigned short orig_id, new_id;
|
||||
int fd, forwardall, flags;
|
||||
int log_id, fd, forwardall, flags;
|
||||
time_t time;
|
||||
unsigned char *hash[HASH_SIZE];
|
||||
#ifdef HAVE_DNSSEC
|
||||
int class;
|
||||
int class, work_counter;
|
||||
struct blockdata *stash; /* Saved reply, whilst we validate */
|
||||
size_t stash_len;
|
||||
struct frec *dependent; /* Query awaiting internally-generated DNSKEY or DS query */
|
||||
@@ -584,6 +682,8 @@ struct frec {
|
||||
#define ACTION_OLD 3
|
||||
#define ACTION_ADD 4
|
||||
#define ACTION_TFTP 5
|
||||
#define ACTION_ARP 6
|
||||
#define ACTION_ARP_DEL 7
|
||||
|
||||
#define LEASE_NEW 1 /* newly created */
|
||||
#define LEASE_CHANGED 2 /* modified */
|
||||
@@ -610,6 +710,8 @@ struct dhcp_lease {
|
||||
unsigned char *extradata;
|
||||
unsigned int extradata_len, extradata_size;
|
||||
int last_interface;
|
||||
int new_interface; /* save possible originated interface */
|
||||
int new_prefixlen; /* and its prefix length */
|
||||
#ifdef HAVE_DHCP6
|
||||
struct in6_addr addr6;
|
||||
int iaid;
|
||||
@@ -640,6 +742,12 @@ struct tag_if {
|
||||
struct tag_if *next;
|
||||
};
|
||||
|
||||
struct delay_config {
|
||||
int delay;
|
||||
struct dhcp_netid *netid;
|
||||
struct delay_config *next;
|
||||
};
|
||||
|
||||
struct hwaddr_config {
|
||||
int hwaddr_len, hwaddr_type;
|
||||
unsigned char hwaddr[DHCP_CHADDR_MAX];
|
||||
@@ -726,7 +834,7 @@ struct pxe_service {
|
||||
#define MATCH_REMOTE 4
|
||||
#define MATCH_SUBSCRIBER 5
|
||||
|
||||
/* vendorclass, userclass, remote-id or cicuit-id */
|
||||
/* vendorclass, userclass, remote-id or circuit-id */
|
||||
struct dhcp_vendor {
|
||||
int len, match_type;
|
||||
unsigned int enterprise;
|
||||
@@ -754,7 +862,7 @@ struct cond_domain {
|
||||
#ifdef HAVE_IPV6
|
||||
struct in6_addr start6, end6;
|
||||
#endif
|
||||
int is6;
|
||||
int is6, indexed;
|
||||
struct cond_domain *next;
|
||||
};
|
||||
|
||||
@@ -768,7 +876,8 @@ struct prefix_class {
|
||||
|
||||
struct ra_interface {
|
||||
char *name;
|
||||
int interval, lifetime, prio;
|
||||
char *mtu_name;
|
||||
int interval, lifetime, prio, mtu;
|
||||
struct ra_interface *next;
|
||||
};
|
||||
|
||||
@@ -794,7 +903,7 @@ struct dhcp_context {
|
||||
#define CONTEXT_NETMASK (1u<<1)
|
||||
#define CONTEXT_BRDCAST (1u<<2)
|
||||
#define CONTEXT_PROXY (1u<<3)
|
||||
#define CONTEXT_RA_ONLY (1u<<4)
|
||||
#define CONTEXT_RA_ROUTER (1u<<4)
|
||||
#define CONTEXT_RA_DONE (1u<<5)
|
||||
#define CONTEXT_RA_NAME (1u<<6)
|
||||
#define CONTEXT_RA_STATELESS (1u<<7)
|
||||
@@ -808,7 +917,7 @@ struct dhcp_context {
|
||||
#define CONTEXT_USED (1u<<15)
|
||||
#define CONTEXT_OLD (1u<<16)
|
||||
#define CONTEXT_V6 (1u<<17)
|
||||
|
||||
#define CONTEXT_RA_OFF_LINK (1u<<18)
|
||||
|
||||
struct ping_result {
|
||||
struct in_addr addr;
|
||||
@@ -845,6 +954,7 @@ struct addr_list {
|
||||
struct tftp_prefix {
|
||||
char *interface;
|
||||
char *prefix;
|
||||
int missing;
|
||||
struct tftp_prefix *next;
|
||||
};
|
||||
|
||||
@@ -863,6 +973,7 @@ extern struct daemon {
|
||||
unsigned int options, options2;
|
||||
struct resolvc default_resolv, *resolv_files;
|
||||
time_t last_resolv;
|
||||
char *servers_file;
|
||||
struct mx_srv_record *mxnames;
|
||||
struct naptr *naptr;
|
||||
struct txt_record *txt, *rr;
|
||||
@@ -872,9 +983,9 @@ extern struct daemon {
|
||||
struct auth_zone *auth_zones;
|
||||
struct interface_name *int_names;
|
||||
char *mxtarget;
|
||||
int addr4_netmask;
|
||||
int addr6_netmask;
|
||||
char *lease_file;
|
||||
struct mysubnet *add_subnet4;
|
||||
struct mysubnet *add_subnet6;
|
||||
char *lease_file;
|
||||
char *username, *groupname, *scriptuser;
|
||||
char *luascript;
|
||||
char *authserver, *hostmaster;
|
||||
@@ -886,15 +997,16 @@ extern struct daemon {
|
||||
char *runfile;
|
||||
char *lease_change_command;
|
||||
struct iname *if_names, *if_addrs, *if_except, *dhcp_except, *auth_peers, *tftp_interfaces;
|
||||
struct bogus_addr *bogus_addr;
|
||||
struct bogus_addr *bogus_addr, *ignore_addr;
|
||||
struct server *servers;
|
||||
struct ipsets *ipsets;
|
||||
int log_fac; /* log facility */
|
||||
char *log_file; /* optional log file */
|
||||
int max_logs; /* queue limit */
|
||||
int cachesize, ftabsize;
|
||||
int port, query_port, min_port;
|
||||
unsigned long local_ttl, neg_ttl, max_ttl, max_cache_ttl, auth_ttl;
|
||||
int port, query_port, min_port, max_port;
|
||||
unsigned long local_ttl, neg_ttl, max_ttl, min_cache_ttl, max_cache_ttl, auth_ttl, dhcp_ttl, use_dhcp_ttl;
|
||||
char *dns_client_id;
|
||||
struct hostsfile *addn_hosts;
|
||||
struct dhcp_context *dhcp, *dhcp6;
|
||||
struct ra_interface *ra_interfaces;
|
||||
@@ -907,13 +1019,14 @@ extern struct daemon {
|
||||
struct tag_if *tag_if;
|
||||
struct addr_list *override_relays;
|
||||
struct dhcp_relay *relay4, *relay6;
|
||||
struct delay_config *delay_conf;
|
||||
int override;
|
||||
int enable_pxe;
|
||||
int doing_ra, doing_dhcp6;
|
||||
struct dhcp_netid_list *dhcp_ignore, *dhcp_ignore_names, *dhcp_gen_names;
|
||||
struct dhcp_netid_list *force_broadcast, *bootp_dynamic;
|
||||
struct hostsfile *dhcp_hosts_file, *dhcp_opts_file;
|
||||
int dhcp_max, tftp_max;
|
||||
struct hostsfile *dhcp_hosts_file, *dhcp_opts_file, *dynamic_dirs;
|
||||
int dhcp_max, tftp_max, tftp_mtu;
|
||||
int dhcp_server_port, dhcp_client_port;
|
||||
int start_tftp_port, end_tftp_port;
|
||||
unsigned int min_leasetime;
|
||||
@@ -924,12 +1037,15 @@ extern struct daemon {
|
||||
unsigned int duid_enterprise, duid_config_len;
|
||||
unsigned char *duid_config;
|
||||
char *dbus_name;
|
||||
char *dump_file;
|
||||
int dump_mask;
|
||||
unsigned long soa_sn, soa_refresh, soa_retry, soa_expiry;
|
||||
#ifdef OPTION6_PREFIX_CLASS
|
||||
struct prefix_class *prefix_classes;
|
||||
#endif
|
||||
#ifdef HAVE_DNSSEC
|
||||
struct dnskey *dnskeys;
|
||||
struct ds_config *ds;
|
||||
char *timestamp_file;
|
||||
#endif
|
||||
|
||||
/* globally used stuff for DNS */
|
||||
@@ -938,6 +1054,11 @@ extern struct daemon {
|
||||
char *namebuff; /* MAXDNAME size buffer */
|
||||
#ifdef HAVE_DNSSEC
|
||||
char *keyname; /* MAXDNAME size buffer */
|
||||
char *workspacename; /* ditto */
|
||||
char *rr_status; /* flags for individual RRs */
|
||||
int rr_status_sz;
|
||||
int dnssec_no_time_check;
|
||||
int back_to_the_future;
|
||||
#endif
|
||||
unsigned int local_answer, queries_forwarded, auth_answer;
|
||||
struct frec *frec_list;
|
||||
@@ -953,9 +1074,15 @@ extern struct daemon {
|
||||
pid_t tcp_pids[MAX_PROCS];
|
||||
struct randfd randomsocks[RANDOM_SOCKS];
|
||||
int v6pktinfo;
|
||||
struct addrlist *interface_addrs; /* list of all addresses/prefix lengths associated with all local interfaces */
|
||||
int log_id, log_display_id; /* ids of transactions for logging */
|
||||
union mysockaddr *log_source_addr;
|
||||
|
||||
/* DHCP state */
|
||||
int dhcpfd, helperfd, pxefd;
|
||||
#ifdef HAVE_INOTIFY
|
||||
int inotifyfd;
|
||||
#endif
|
||||
#if defined(HAVE_LINUX_NETWORK)
|
||||
int netlinkfd;
|
||||
#elif defined(HAVE_BSD_NETWORK)
|
||||
@@ -984,13 +1111,19 @@ extern struct daemon {
|
||||
|
||||
/* utility string buffer, hold max sized IP address as string */
|
||||
char *addrbuff;
|
||||
char *addrbuff2; /* only allocated when OPT_EXTRALOG */
|
||||
|
||||
#ifdef HAVE_DUMPFILE
|
||||
/* file for packet dumps. */
|
||||
int dumpfd;
|
||||
#endif
|
||||
} *daemon;
|
||||
|
||||
/* cache.c */
|
||||
void cache_init(void);
|
||||
void next_uid(struct crec *crecp);
|
||||
void log_query(unsigned int flags, char *name, struct all_addr *addr, char *arg);
|
||||
char *record_source(int index);
|
||||
char *record_source(unsigned int index);
|
||||
char *querystr(char *desc, unsigned short type);
|
||||
struct crec *cache_find_by_addr(struct crec *crecp,
|
||||
struct all_addr *addr, time_t now,
|
||||
@@ -1006,9 +1139,14 @@ void cache_add_dhcp_entry(char *host_name, int prot, struct all_addr *host_addre
|
||||
struct in_addr a_record_from_hosts(char *name, time_t now);
|
||||
void cache_unhash_dhcp(void);
|
||||
void dump_cache(time_t now);
|
||||
#ifndef NO_ID
|
||||
int cache_make_stat(struct txt_record *t);
|
||||
#endif
|
||||
char *cache_get_name(struct crec *crecp);
|
||||
char *cache_get_cname_target(struct crec *crecp);
|
||||
struct crec *cache_enumerate(int init);
|
||||
int read_hostsfile(char *filename, unsigned int index, int cache_size,
|
||||
struct crec **rhash, int hashsz);
|
||||
|
||||
/* blockdata.c */
|
||||
#ifdef HAVE_DNSSEC
|
||||
@@ -1032,30 +1170,25 @@ int extract_name(struct dns_header *header, size_t plen, unsigned char **pp,
|
||||
char *name, int isExtract, int extrabytes);
|
||||
unsigned char *skip_name(unsigned char *ansp, struct dns_header *header, size_t plen, int extrabytes);
|
||||
unsigned char *skip_questions(struct dns_header *header, size_t plen);
|
||||
unsigned char *skip_section(unsigned char *ansp, int count, struct dns_header *header, size_t plen);
|
||||
unsigned int extract_request(struct dns_header *header, size_t qlen,
|
||||
char *name, unsigned short *typep);
|
||||
size_t setup_reply(struct dns_header *header, size_t qlen,
|
||||
struct all_addr *addrp, unsigned int flags,
|
||||
unsigned long local_ttl);
|
||||
int extract_addresses(struct dns_header *header, size_t qlen, char *namebuff,
|
||||
time_t now, char **ipsets, int is_sign, int checkrebind,
|
||||
int no_cache, int secure, int *doctored);
|
||||
unsigned long ttl);
|
||||
int extract_addresses(struct dns_header *header, size_t qlen, char *name,
|
||||
time_t now, char **ipsets, int is_sign, int check_rebind,
|
||||
int no_cache_dnssec, int secure, int *doctored);
|
||||
size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
||||
struct in_addr local_addr, struct in_addr local_netmask, time_t now);
|
||||
struct in_addr local_addr, struct in_addr local_netmask,
|
||||
time_t now, int ad_reqd, int do_bit, int have_pseudoheader);
|
||||
int check_for_bogus_wildcard(struct dns_header *header, size_t qlen, char *name,
|
||||
struct bogus_addr *addr, time_t now);
|
||||
unsigned char *find_pseudoheader(struct dns_header *header, size_t plen,
|
||||
size_t *len, unsigned char **p, int *is_sign);
|
||||
struct bogus_addr *baddr, time_t now);
|
||||
int check_for_ignored_address(struct dns_header *header, size_t qlen, struct bogus_addr *baddr);
|
||||
int check_for_local_domain(char *name, time_t now);
|
||||
unsigned int questions_crc(struct dns_header *header, size_t plen, char *buff);
|
||||
unsigned int questions_crc(struct dns_header *header, size_t plen, char *name);
|
||||
size_t resize_packet(struct dns_header *header, size_t plen,
|
||||
unsigned char *pheader, size_t hlen);
|
||||
size_t add_mac(struct dns_header *header, size_t plen, char *limit, union mysockaddr *l3);
|
||||
size_t add_source_addr(struct dns_header *header, size_t plen, char *limit, union mysockaddr *source);
|
||||
#ifdef HAVE_DNSSEC
|
||||
size_t add_do_bit(struct dns_header *header, size_t plen, char *limit);
|
||||
#endif
|
||||
int check_source(struct dns_header *header, size_t plen, unsigned char *pseudoheader, union mysockaddr *peer);
|
||||
int add_resource_record(struct dns_header *header, char *limit, int *truncp,
|
||||
int nameoffset, unsigned char **pp, unsigned long ttl,
|
||||
int *offset, unsigned short type, unsigned short class, char *format, ...);
|
||||
@@ -1068,25 +1201,39 @@ int private_net(struct in_addr addr, int ban_localhost);
|
||||
/* auth.c */
|
||||
#ifdef HAVE_AUTH
|
||||
size_t answer_auth(struct dns_header *header, char *limit, size_t qlen,
|
||||
time_t now, union mysockaddr *peer_addr, int local_query);
|
||||
time_t now, union mysockaddr *peer_addr, int local_query,
|
||||
int do_bit, int have_pseudoheader);
|
||||
int in_zone(struct auth_zone *zone, char *name, char **cut);
|
||||
#endif
|
||||
|
||||
/* dnssec.c */
|
||||
size_t dnssec_generate_query(struct dns_header *header, char *end, char *name, int class, int type, union mysockaddr *addr);
|
||||
int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t n, char *name, char *keyname, int class);
|
||||
size_t dnssec_generate_query(struct dns_header *header, unsigned char *end, char *name, int class, int type, union mysockaddr *addr, int edns_pktsz);
|
||||
int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, int class);
|
||||
int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, int class);
|
||||
int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, int *class);
|
||||
int dnskey_keytag(int alg, int flags, unsigned char *rdata, int rdlen);
|
||||
int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, int *class,
|
||||
int check_unsigned, int *neganswer, int *nons);
|
||||
int dnskey_keytag(int alg, int flags, unsigned char *key, int keylen);
|
||||
size_t filter_rrsigs(struct dns_header *header, size_t plen);
|
||||
unsigned char* hash_questions(struct dns_header *header, size_t plen, char *name);
|
||||
int setup_timestamp(void);
|
||||
|
||||
/* crypto.c */
|
||||
const struct nettle_hash *hash_find(char *name);
|
||||
int hash_init(const struct nettle_hash *hash, void **ctxp, unsigned char **digestp);
|
||||
int verify(struct blockdata *key_data, unsigned int key_len, unsigned char *sig, size_t sig_len,
|
||||
unsigned char *digest, size_t digest_len, int algo);
|
||||
char *ds_digest_name(int digest);
|
||||
char *algo_digest_name(int algo);
|
||||
char *nsec3_digest_name(int digest);
|
||||
|
||||
/* util.c */
|
||||
void rand_init(void);
|
||||
unsigned short rand16(void);
|
||||
u32 rand32(void);
|
||||
u64 rand64(void);
|
||||
int legal_hostname(char *c);
|
||||
char *canonicalise(char *s, int *nomem);
|
||||
unsigned char *do_rfc1035_name(unsigned char *p, char *sval);
|
||||
int legal_hostname(char *name);
|
||||
char *canonicalise(char *in, int *nomem);
|
||||
unsigned char *do_rfc1035_name(unsigned char *p, char *sval, char *limit);
|
||||
void *safe_malloc(size_t size);
|
||||
void safe_pipe(int *fd, int read_noblock);
|
||||
void *whine_malloc(size_t size);
|
||||
@@ -1094,36 +1241,36 @@ int sa_len(union mysockaddr *addr);
|
||||
int sockaddr_isequal(union mysockaddr *s1, union mysockaddr *s2);
|
||||
int hostname_isequal(const char *a, const char *b);
|
||||
time_t dnsmasq_time(void);
|
||||
int netmask_length(struct in_addr mask);
|
||||
int is_same_net(struct in_addr a, struct in_addr b, struct in_addr mask);
|
||||
#ifdef HAVE_IPV6
|
||||
int is_same_net6(struct in6_addr *a, struct in6_addr *b, int prefixlen);
|
||||
u64 addr6part(struct in6_addr *addr);
|
||||
void setaddr6part(struct in6_addr *addr, u64 host);
|
||||
#endif
|
||||
int retry_send(void);
|
||||
int retry_send(ssize_t rc);
|
||||
void prettyprint_time(char *buf, unsigned int t);
|
||||
int prettyprint_addr(union mysockaddr *addr, char *buf);
|
||||
int parse_hex(char *in, unsigned char *out, int maxlen,
|
||||
unsigned int *wildcard_mask, int *mac_type);
|
||||
#ifdef HAVE_DNSSEC
|
||||
int parse_base64(char *in, char *out);
|
||||
#endif
|
||||
int memcmp_masked(unsigned char *a, unsigned char *b, int len,
|
||||
unsigned int mask);
|
||||
int expand_buf(struct iovec *iov, size_t size);
|
||||
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 wildcard_match(const char* wildcard, const char* match);
|
||||
int wildcard_matchn(const char* wildcard, const char* match, int num);
|
||||
|
||||
/* log.c */
|
||||
void die(char *message, char *arg1, int exit_code);
|
||||
int log_start(struct passwd *ent_pw, int errfd);
|
||||
int log_reopen(char *log_file);
|
||||
|
||||
void my_syslog(int priority, const char *format, ...);
|
||||
void set_log_writer(fd_set *set, int *maxfdp);
|
||||
void check_log_writer(fd_set *set);
|
||||
|
||||
void set_log_writer(void);
|
||||
void check_log_writer(int force);
|
||||
void flush_log(void);
|
||||
|
||||
/* option.c */
|
||||
@@ -1131,11 +1278,13 @@ void read_opts (int argc, char **argv, char *compile_opts);
|
||||
char *option_string(int prot, unsigned int opt, unsigned char *val,
|
||||
int opt_len, char *buf, int buf_len);
|
||||
void reread_dhcp(void);
|
||||
void read_servers_file(void);
|
||||
void set_option_bool(unsigned int opt);
|
||||
void reset_option_bool(unsigned int opt);
|
||||
struct hostsfile *expand_filelist(struct hostsfile *list);
|
||||
char *parse_server(char *arg, union mysockaddr *addr,
|
||||
union mysockaddr *source_addr, char *interface, int *flags);
|
||||
int option_read_dynfile(char *file, int flags);
|
||||
|
||||
/* forward.c */
|
||||
void reply_query(int fd, int family, time_t now);
|
||||
@@ -1147,21 +1296,32 @@ struct frec *get_new_frec(time_t now, int *wait, int force);
|
||||
int send_from(int fd, int nowild, char *packet, size_t len,
|
||||
union mysockaddr *to, struct all_addr *source,
|
||||
unsigned int iface);
|
||||
void resend_query(void);
|
||||
struct randfd *allocate_rfd(int family);
|
||||
void free_rfd(struct randfd *rfd);
|
||||
|
||||
/* network.c */
|
||||
int indextoname(int fd, int index, char *name);
|
||||
int local_bind(int fd, union mysockaddr *addr, char *intname, int is_tcp);
|
||||
int local_bind(int fd, union mysockaddr *addr, char *intname, unsigned int ifindex, int is_tcp);
|
||||
int random_sock(int family);
|
||||
void pre_allocate_sfds(void);
|
||||
int reload_servers(char *fname);
|
||||
void mark_servers(int flag);
|
||||
void cleanup_servers(void);
|
||||
void add_update_server(int flags,
|
||||
union mysockaddr *addr,
|
||||
union mysockaddr *source_addr,
|
||||
const char *interface,
|
||||
const char *domain);
|
||||
void check_servers(void);
|
||||
int enumerate_interfaces(int reset);
|
||||
void create_wildcard_listeners(void);
|
||||
void create_bound_listeners(int die);
|
||||
void create_bound_listeners(int dienow);
|
||||
void warn_bound_listeners(void);
|
||||
void warn_wild_labels(void);
|
||||
void warn_int_names(void);
|
||||
int is_dad_listeners(void);
|
||||
int iface_check(int family, struct all_addr *addr, char *name, int *auth_dns);
|
||||
int iface_check(int family, struct all_addr *addr, char *name, int *auth);
|
||||
int loopback_exception(int fd, int family, struct all_addr *addr, char *name);
|
||||
int label_exception(int index, int family, struct all_addr *addr);
|
||||
int fix_fd(int fd);
|
||||
@@ -1182,14 +1342,16 @@ void newaddress(time_t now);
|
||||
void dhcp_init(void);
|
||||
void dhcp_packet(time_t now, int pxe_fd);
|
||||
struct dhcp_context *address_available(struct dhcp_context *context,
|
||||
struct in_addr addr,
|
||||
struct in_addr taddr,
|
||||
struct dhcp_netid *netids);
|
||||
struct dhcp_context *narrow_context(struct dhcp_context *context,
|
||||
struct in_addr taddr,
|
||||
struct dhcp_netid *netids);
|
||||
struct ping_result *do_icmp_ping(time_t now, struct in_addr addr,
|
||||
unsigned int hash, int loopback);
|
||||
int address_allocate(struct dhcp_context *context,
|
||||
struct in_addr *addrp, unsigned char *hwaddr, int hw_len,
|
||||
struct dhcp_netid *netids, time_t now);
|
||||
struct dhcp_netid *netids, time_t now, int loopback);
|
||||
void dhcp_read_ethers(void);
|
||||
struct dhcp_config *config_find_by_address(struct dhcp_config *configs, struct in_addr addr);
|
||||
char *host_from_dns(struct in_addr addr);
|
||||
@@ -1214,9 +1376,10 @@ void lease_update_slaac(time_t now);
|
||||
void lease_set_iaid(struct dhcp_lease *lease, int iaid);
|
||||
void lease_make_duid(time_t now);
|
||||
#endif
|
||||
void lease_set_hwaddr(struct dhcp_lease *lease, unsigned char *hwaddr,
|
||||
unsigned char *clid, int hw_len, int hw_type, int clid_len, time_t now, int force);
|
||||
void lease_set_hostname(struct dhcp_lease *lease, char *name, int auth, char *domain, char *config_domain);
|
||||
void lease_set_hwaddr(struct dhcp_lease *lease, const unsigned char *hwaddr,
|
||||
const unsigned char *clid, int hw_len, int hw_type,
|
||||
int clid_len, time_t now, int force);
|
||||
void lease_set_hostname(struct dhcp_lease *lease, const char *name, int auth, char *domain, char *config_domain);
|
||||
void lease_set_expires(struct dhcp_lease *lease, unsigned int len, time_t now);
|
||||
void lease_set_interface(struct dhcp_lease *lease, int interface, time_t now);
|
||||
struct dhcp_lease *lease_find_by_client(unsigned char *hwaddr, int hw_len, int hw_type,
|
||||
@@ -1237,7 +1400,8 @@ void lease_add_extradata(struct dhcp_lease *lease, unsigned char *data,
|
||||
/* rfc2131.c */
|
||||
#ifdef HAVE_DHCP
|
||||
size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
|
||||
size_t sz, time_t now, int unicast_dest, int *is_inform, int pxe_fd, struct in_addr fallback);
|
||||
size_t sz, time_t now, int unicast_dest, int loopback,
|
||||
int *is_inform, int pxe, struct in_addr fallback, time_t recvtime);
|
||||
unsigned char *extended_hwaddr(int hwtype, int hwlen, unsigned char *hwaddr,
|
||||
int clid_len, unsigned char *clid, int *len_out);
|
||||
#endif
|
||||
@@ -1246,16 +1410,17 @@ unsigned char *extended_hwaddr(int hwtype, int hwlen, unsigned char *hwaddr,
|
||||
#ifdef HAVE_DHCP
|
||||
int make_icmp_sock(void);
|
||||
int icmp_ping(struct in_addr addr);
|
||||
int delay_dhcp(time_t start, int sec, int fd, uint32_t addr, unsigned short id);
|
||||
#endif
|
||||
void queue_event(int event);
|
||||
void send_alarm(time_t event, time_t now);
|
||||
void send_event(int fd, int event, int data, char *msg);
|
||||
void clear_cache_and_reload(time_t now);
|
||||
void poll_resolv(int force, int do_reload, time_t now);
|
||||
|
||||
/* netlink.c */
|
||||
#ifdef HAVE_LINUX_NETWORK
|
||||
void netlink_init(void);
|
||||
void netlink_multicast(time_t now);
|
||||
void netlink_multicast(void);
|
||||
#endif
|
||||
|
||||
/* bpf.c */
|
||||
@@ -1264,7 +1429,7 @@ void init_bpf(void);
|
||||
void send_via_bpf(struct dhcp_packet *mess, size_t len,
|
||||
struct in_addr iface_addr, struct ifreq *ifr);
|
||||
void route_init(void);
|
||||
void route_sock(time_t now);
|
||||
void route_sock(void);
|
||||
#endif
|
||||
|
||||
/* bpf.c or netlink.c */
|
||||
@@ -1273,8 +1438,8 @@ int iface_enumerate(int family, void *parm, int (callback)());
|
||||
/* dbus.c */
|
||||
#ifdef HAVE_DBUS
|
||||
char *dbus_init(void);
|
||||
void check_dbus_listeners(fd_set *rset, fd_set *wset, fd_set *eset);
|
||||
void set_dbus_listeners(int *maxfdp, fd_set *rset, fd_set *wset, fd_set *eset);
|
||||
void check_dbus_listeners(void);
|
||||
void set_dbus_listeners(void);
|
||||
# ifdef HAVE_DHCP
|
||||
void emit_dbus_signal(int action, struct dhcp_lease *lease, char *hostname);
|
||||
# endif
|
||||
@@ -1295,13 +1460,15 @@ void queue_script(int action, struct dhcp_lease *lease,
|
||||
#ifdef HAVE_TFTP
|
||||
void queue_tftp(off_t file_len, char *filename, union mysockaddr *peer);
|
||||
#endif
|
||||
void queue_arp(int action, unsigned char *mac, int maclen,
|
||||
int family, struct all_addr *addr);
|
||||
int helper_buf_empty(void);
|
||||
#endif
|
||||
|
||||
/* tftp.c */
|
||||
#ifdef HAVE_TFTP
|
||||
void tftp_request(struct listener *listen, time_t now);
|
||||
void check_tftp_listeners(fd_set *rset, time_t now);
|
||||
void check_tftp_listeners(time_t now);
|
||||
int do_tftp_script_run(void);
|
||||
#endif
|
||||
|
||||
@@ -1331,7 +1498,7 @@ struct dhcp_config *config_find_by_address6(struct dhcp_config *configs, struct
|
||||
void make_duid(time_t now);
|
||||
void dhcp_construct_contexts(time_t now);
|
||||
void get_client_mac(struct in6_addr *client, int iface, unsigned char *mac,
|
||||
unsigned int *maclenp, unsigned int *mactypep);
|
||||
unsigned int *maclenp, unsigned int *mactypep, time_t now);
|
||||
#endif
|
||||
|
||||
/* rfc3315.c */
|
||||
@@ -1339,7 +1506,8 @@ void get_client_mac(struct in6_addr *client, int iface, unsigned char *mac,
|
||||
unsigned short dhcp6_reply(struct dhcp_context *context, int interface, char *iface_name,
|
||||
struct in6_addr *fallback, struct in6_addr *ll_addr, struct in6_addr *ula_addr,
|
||||
size_t sz, struct in6_addr *client_addr, time_t now);
|
||||
void relay_upstream6(struct dhcp_relay *relay, ssize_t sz, struct in6_addr *peer_address, u32 scope_id);
|
||||
void relay_upstream6(struct dhcp_relay *relay, ssize_t sz, struct in6_addr *peer_address,
|
||||
u32 scope_id, time_t now);
|
||||
|
||||
unsigned short relay_reply6( struct sockaddr_in6 *peer, ssize_t sz, char *arrival_interface);
|
||||
#endif
|
||||
@@ -1348,10 +1516,10 @@ unsigned short relay_reply6( struct sockaddr_in6 *peer, ssize_t sz, char *arriva
|
||||
#ifdef HAVE_DHCP
|
||||
void dhcp_common_init(void);
|
||||
ssize_t recv_dhcp_packet(int fd, struct msghdr *msg);
|
||||
struct dhcp_netid *run_tag_if(struct dhcp_netid *input);
|
||||
struct dhcp_netid *run_tag_if(struct dhcp_netid *tags);
|
||||
struct dhcp_netid *option_filter(struct dhcp_netid *tags, struct dhcp_netid *context_tags,
|
||||
struct dhcp_opt *opts);
|
||||
int match_netid(struct dhcp_netid *check, struct dhcp_netid *pool, int negonly);
|
||||
int match_netid(struct dhcp_netid *check, struct dhcp_netid *pool, int tagnotneeded);
|
||||
char *strip_hostname(char *hostname);
|
||||
void log_tags(struct dhcp_netid *netid, u32 xid);
|
||||
int match_bytes(struct dhcp_opt *o, unsigned char *p, int len);
|
||||
@@ -1381,6 +1549,7 @@ void log_relay(int family, struct dhcp_relay *relay);
|
||||
/* outpacket.c */
|
||||
#ifdef HAVE_DHCP6
|
||||
void end_opt6(int container);
|
||||
void reset_counter(void);
|
||||
int save_counter(int newval);
|
||||
void *expand(size_t headroom);
|
||||
int new_opt6(int opt);
|
||||
@@ -1396,7 +1565,7 @@ void put_opt6_string(char *s);
|
||||
void ra_init(time_t now);
|
||||
void icmp6_packet(time_t now);
|
||||
time_t periodic_ra(time_t now);
|
||||
void ra_start_unsolicted(time_t now, struct dhcp_context *context);
|
||||
void ra_start_unsolicited(time_t now, struct dhcp_context *context);
|
||||
#endif
|
||||
|
||||
/* slaac.c */
|
||||
@@ -1405,3 +1574,47 @@ void slaac_add_addrs(struct dhcp_lease *lease, time_t now, int force);
|
||||
time_t periodic_slaac(time_t now, struct dhcp_lease *leases);
|
||||
void slaac_ping_reply(struct in6_addr *sender, unsigned char *packet, char *interface, struct dhcp_lease *leases);
|
||||
#endif
|
||||
|
||||
/* loop.c */
|
||||
#ifdef HAVE_LOOP
|
||||
void loop_send_probes(void);
|
||||
int detect_loop(char *query, int type);
|
||||
#endif
|
||||
|
||||
/* inotify.c */
|
||||
#ifdef HAVE_INOTIFY
|
||||
void inotify_dnsmasq_init(void);
|
||||
int inotify_check(time_t now);
|
||||
void set_dynamic_inotify(int flag, int total_size, struct crec **rhash, int revhashsz);
|
||||
#endif
|
||||
|
||||
/* poll.c */
|
||||
void poll_reset(void);
|
||||
int poll_check(int fd, short event);
|
||||
void poll_listen(int fd, short event);
|
||||
int do_poll(int timeout);
|
||||
|
||||
/* rrfilter.c */
|
||||
size_t rrfilter(struct dns_header *header, size_t plen, int mode);
|
||||
u16 *rrfilter_desc(int type);
|
||||
int expand_workspace(unsigned char ***wkspc, int *szp, int new);
|
||||
|
||||
/* edns0.c */
|
||||
unsigned char *find_pseudoheader(struct dns_header *header, size_t plen,
|
||||
size_t *len, unsigned char **p, int *is_sign, int *is_last);
|
||||
size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *limit,
|
||||
unsigned short udp_sz, int optno, unsigned char *opt, size_t optlen, int set_do, int replace);
|
||||
size_t add_do_bit(struct dns_header *header, size_t plen, unsigned char *limit);
|
||||
size_t add_edns0_config(struct dns_header *header, size_t plen, unsigned char *limit,
|
||||
union mysockaddr *source, time_t now, int *check_subnet);
|
||||
int check_source(struct dns_header *header, size_t plen, unsigned char *pseudoheader, union mysockaddr *peer);
|
||||
|
||||
/* arp.c */
|
||||
int find_mac(union mysockaddr *addr, unsigned char *mac, int lazy, time_t now);
|
||||
int do_arp_script_run(void);
|
||||
|
||||
/* dump.c */
|
||||
#ifdef HAVE_DUMPFILE
|
||||
void dump_init(void);
|
||||
void dump_packet(int mask, void *packet, size_t len, union mysockaddr *src, union mysockaddr *dst);
|
||||
#endif
|
||||
|
||||
2112
src/dnssec.c
2112
src/dnssec.c
File diff suppressed because it is too large
Load Diff
227
src/domain.c
227
src/domain.c
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2014 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2018 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
|
||||
@@ -55,70 +55,133 @@ int is_name_synthetic(int flags, char *name, struct all_addr *addr)
|
||||
|
||||
if (pref && *pref != 0)
|
||||
continue; /* prefix match fail */
|
||||
|
||||
/* NB, must not alter name if we return zero */
|
||||
for (p = tail; *p; p++)
|
||||
|
||||
if (c->indexed)
|
||||
{
|
||||
char c = *p;
|
||||
|
||||
if ((c >='0' && c <= '9') || c == '-')
|
||||
continue;
|
||||
|
||||
#ifdef HAVE_IPV6
|
||||
if (prot == AF_INET6 && ((c >='A' && c <= 'F') || (c >='a' && c <= 'f')))
|
||||
continue;
|
||||
#endif
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (*p != '.')
|
||||
continue;
|
||||
|
||||
*p = 0;
|
||||
|
||||
/* swap . or : for - */
|
||||
for (p = tail; *p; p++)
|
||||
if (*p == '-')
|
||||
{
|
||||
if (prot == AF_INET)
|
||||
*p = '.';
|
||||
#ifdef HAVE_IPV6
|
||||
else
|
||||
*p = ':';
|
||||
#endif
|
||||
}
|
||||
|
||||
if (hostname_isequal(c->domain, p+1) && inet_pton(prot, tail, addr))
|
||||
{
|
||||
if (prot == AF_INET)
|
||||
for (p = tail; *p; p++)
|
||||
{
|
||||
if (!c->is6 &&
|
||||
ntohl(addr->addr.addr4.s_addr) >= ntohl(c->start.s_addr) &&
|
||||
ntohl(addr->addr.addr4.s_addr) <= ntohl(c->end.s_addr))
|
||||
found = 1;
|
||||
}
|
||||
#ifdef HAVE_IPV6
|
||||
else
|
||||
{
|
||||
u64 addrpart = addr6part(&addr->addr.addr6);
|
||||
char c = *p;
|
||||
|
||||
if (c->is6 &&
|
||||
is_same_net6(&addr->addr.addr6, &c->start6, 64) &&
|
||||
addrpart >= addr6part(&c->start6) &&
|
||||
addrpart <= addr6part(&c->end6))
|
||||
found = 1;
|
||||
if (c < '0' || c > '9')
|
||||
break;
|
||||
}
|
||||
|
||||
if (*p != '.')
|
||||
continue;
|
||||
|
||||
*p = 0;
|
||||
|
||||
if (hostname_isequal(c->domain, p+1))
|
||||
{
|
||||
if (prot == AF_INET)
|
||||
{
|
||||
unsigned int index = atoi(tail);
|
||||
|
||||
if (!c->is6 &&
|
||||
index <= ntohl(c->end.s_addr) - ntohl(c->start.s_addr))
|
||||
{
|
||||
addr->addr.addr4.s_addr = htonl(ntohl(c->start.s_addr) + index);
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
#ifdef HAVE_IPV6
|
||||
else
|
||||
{
|
||||
u64 index = atoll(tail);
|
||||
|
||||
if (c->is6 &&
|
||||
index <= addr6part(&c->end6) - addr6part(&c->start6))
|
||||
{
|
||||
u64 start = addr6part(&c->start6);
|
||||
addr->addr.addr6 = c->start6;
|
||||
setaddr6part(&addr->addr.addr6, start + index);
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
/* NB, must not alter name if we return zero */
|
||||
for (p = tail; *p; p++)
|
||||
{
|
||||
char c = *p;
|
||||
|
||||
if ((c >='0' && c <= '9') || c == '-')
|
||||
continue;
|
||||
|
||||
#ifdef HAVE_IPV6
|
||||
if (prot == AF_INET6 && ((c >='A' && c <= 'F') || (c >='a' && c <= 'f')))
|
||||
continue;
|
||||
#endif
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (*p != '.')
|
||||
continue;
|
||||
|
||||
*p = 0;
|
||||
|
||||
#ifdef HAVE_IPV6
|
||||
if (prot == AF_INET6 && strstr(tail, "--ffff-") == tail)
|
||||
{
|
||||
/* special hack for v4-mapped. */
|
||||
memcpy(tail, "::ffff:", 7);
|
||||
for (p = tail + 7; *p; p++)
|
||||
if (*p == '-')
|
||||
*p = '.';
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* swap . or : for - */
|
||||
for (p = tail; *p; p++)
|
||||
if (*p == '-')
|
||||
{
|
||||
if (prot == AF_INET)
|
||||
*p = '.';
|
||||
#ifdef HAVE_IPV6
|
||||
else
|
||||
*p = ':';
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (hostname_isequal(c->domain, p+1) && inet_pton(prot, tail, addr))
|
||||
{
|
||||
if (prot == AF_INET)
|
||||
{
|
||||
if (!c->is6 &&
|
||||
ntohl(addr->addr.addr4.s_addr) >= ntohl(c->start.s_addr) &&
|
||||
ntohl(addr->addr.addr4.s_addr) <= ntohl(c->end.s_addr))
|
||||
found = 1;
|
||||
}
|
||||
#ifdef HAVE_IPV6
|
||||
else
|
||||
{
|
||||
u64 addrpart = addr6part(&addr->addr.addr6);
|
||||
|
||||
if (c->is6 &&
|
||||
is_same_net6(&addr->addr.addr6, &c->start6, 64) &&
|
||||
addrpart >= addr6part(&c->start6) &&
|
||||
addrpart <= addr6part(&c->end6))
|
||||
found = 1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* restore name */
|
||||
for (p = tail; *p; p++)
|
||||
if (*p == '.' || *p == ':')
|
||||
*p = '-';
|
||||
|
||||
*p = '.';
|
||||
|
||||
|
||||
|
||||
if (found)
|
||||
return 1;
|
||||
}
|
||||
@@ -136,14 +199,22 @@ int is_rev_synth(int flag, struct all_addr *addr, char *name)
|
||||
char *p;
|
||||
|
||||
*name = 0;
|
||||
if (c->prefix)
|
||||
strncpy(name, c->prefix, MAXDNAME - ADDRSTRLEN);
|
||||
if (c->indexed)
|
||||
{
|
||||
unsigned int index = ntohl(addr->addr.addr4.s_addr) - ntohl(c->start.s_addr);
|
||||
snprintf(name, MAXDNAME, "%s%u", c->prefix ? c->prefix : "", index);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (c->prefix)
|
||||
strncpy(name, c->prefix, MAXDNAME - ADDRSTRLEN);
|
||||
|
||||
inet_ntop(AF_INET, &addr->addr.addr4, name + strlen(name), ADDRSTRLEN);
|
||||
for (p = name; *p; p++)
|
||||
if (*p == '.')
|
||||
*p = '-';
|
||||
}
|
||||
|
||||
inet_ntop(AF_INET, &addr->addr.addr4, name + strlen(name), ADDRSTRLEN);
|
||||
for (p = name; *p; p++)
|
||||
if (*p == '.')
|
||||
*p = '-';
|
||||
|
||||
strncat(name, ".", MAXDNAME);
|
||||
strncat(name, c->domain, MAXDNAME);
|
||||
|
||||
@@ -156,22 +227,32 @@ int is_rev_synth(int flag, struct all_addr *addr, char *name)
|
||||
char *p;
|
||||
|
||||
*name = 0;
|
||||
if (c->prefix)
|
||||
strncpy(name, c->prefix, MAXDNAME - ADDRSTRLEN);
|
||||
|
||||
inet_ntop(AF_INET6, &addr->addr.addr6, name + strlen(name), ADDRSTRLEN);
|
||||
|
||||
/* IPv6 presentation address can start with ":", but valid domain names
|
||||
cannot start with "-" so prepend a zero in that case. */
|
||||
if (!c->prefix && *name == ':')
|
||||
if (c->indexed)
|
||||
{
|
||||
*name = '0';
|
||||
inet_ntop(AF_INET6, &addr->addr.addr6, name+1, ADDRSTRLEN);
|
||||
u64 index = addr6part(&addr->addr.addr6) - addr6part(&c->start6);
|
||||
snprintf(name, MAXDNAME, "%s%llu", c->prefix ? c->prefix : "", index);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (c->prefix)
|
||||
strncpy(name, c->prefix, MAXDNAME - ADDRSTRLEN);
|
||||
|
||||
inet_ntop(AF_INET6, &addr->addr.addr6, name + strlen(name), ADDRSTRLEN);
|
||||
|
||||
for (p = name; *p; p++)
|
||||
if (*p == ':')
|
||||
*p = '-';
|
||||
/* IPv6 presentation address can start with ":", but valid domain names
|
||||
cannot start with "-" so prepend a zero in that case. */
|
||||
if (!c->prefix && *name == ':')
|
||||
{
|
||||
*name = '0';
|
||||
inet_ntop(AF_INET6, &addr->addr.addr6, name+1, ADDRSTRLEN);
|
||||
}
|
||||
|
||||
/* V4-mapped have periods.... */
|
||||
for (p = name; *p; p++)
|
||||
if (*p == ':' || *p == '.')
|
||||
*p = '-';
|
||||
|
||||
}
|
||||
|
||||
strncat(name, ".", MAXDNAME);
|
||||
strncat(name, c->domain, MAXDNAME);
|
||||
|
||||
211
src/dump.c
Normal file
211
src/dump.c
Normal file
@@ -0,0 +1,211 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2018 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_DUMPFILE
|
||||
|
||||
static u32 packet_count;
|
||||
|
||||
/* https://wiki.wireshark.org/Development/LibpcapFileFormat */
|
||||
struct pcap_hdr_s {
|
||||
u32 magic_number; /* magic number */
|
||||
u16 version_major; /* major version number */
|
||||
u16 version_minor; /* minor version number */
|
||||
u32 thiszone; /* GMT to local correction */
|
||||
u32 sigfigs; /* accuracy of timestamps */
|
||||
u32 snaplen; /* max length of captured packets, in octets */
|
||||
u32 network; /* data link type */
|
||||
};
|
||||
|
||||
struct pcaprec_hdr_s {
|
||||
u32 ts_sec; /* timestamp seconds */
|
||||
u32 ts_usec; /* timestamp microseconds */
|
||||
u32 incl_len; /* number of octets of packet saved in file */
|
||||
u32 orig_len; /* actual length of packet */
|
||||
};
|
||||
|
||||
|
||||
void dump_init(void)
|
||||
{
|
||||
struct stat buf;
|
||||
struct pcap_hdr_s header;
|
||||
struct pcaprec_hdr_s pcap_header;
|
||||
|
||||
packet_count = 0;
|
||||
|
||||
if (stat(daemon->dump_file, &buf) == -1)
|
||||
{
|
||||
/* doesn't exist, create and add header */
|
||||
header.magic_number = 0xa1b2c3d4;
|
||||
header.version_major = 2;
|
||||
header.version_minor = 4;
|
||||
header.thiszone = 0;
|
||||
header.sigfigs = 0;
|
||||
header.snaplen = daemon->edns_pktsz + 200; /* slop for IP/UDP headers */
|
||||
header.network = 101; /* DLT_RAW http://www.tcpdump.org/linktypes.html */
|
||||
|
||||
if (errno != ENOENT ||
|
||||
(daemon->dumpfd = creat(daemon->dump_file, S_IRUSR | S_IWUSR)) == -1 ||
|
||||
!read_write(daemon->dumpfd, (void *)&header, sizeof(header), 0))
|
||||
die(_("cannot create %s: %s"), daemon->dump_file, EC_FILE);
|
||||
}
|
||||
else if ((daemon->dumpfd = open(daemon->dump_file, O_APPEND | O_RDWR)) == -1 ||
|
||||
!read_write(daemon->dumpfd, (void *)&header, sizeof(header), 1))
|
||||
die(_("cannot access %s: %s"), daemon->dump_file, EC_FILE);
|
||||
else if (header.magic_number != 0xa1b2c3d4)
|
||||
die(_("bad header in %s"), daemon->dump_file, EC_FILE);
|
||||
else
|
||||
{
|
||||
/* count existing records */
|
||||
while (read_write(daemon->dumpfd, (void *)&pcap_header, sizeof(pcap_header), 1))
|
||||
{
|
||||
lseek(daemon->dumpfd, pcap_header.incl_len, SEEK_CUR);
|
||||
packet_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dump_packet(int mask, void *packet, size_t len, union mysockaddr *src, union mysockaddr *dst)
|
||||
{
|
||||
struct ip ip;
|
||||
#ifdef HAVE_IPV6
|
||||
struct ip6_hdr ip6;
|
||||
int family;
|
||||
#endif
|
||||
struct udphdr {
|
||||
u16 uh_sport; /* source port */
|
||||
u16 uh_dport; /* destination port */
|
||||
u16 uh_ulen; /* udp length */
|
||||
u16 uh_sum; /* udp checksum */
|
||||
} udp;
|
||||
struct pcaprec_hdr_s pcap_header;
|
||||
struct timeval time;
|
||||
u32 i, sum;
|
||||
void *iphdr;
|
||||
size_t ipsz;
|
||||
int rc;
|
||||
|
||||
if (daemon->dumpfd == -1 || !(mask & daemon->dump_mask))
|
||||
return;
|
||||
|
||||
/* So wireshark can Id the packet. */
|
||||
udp.uh_sport = udp.uh_dport = htons(NAMESERVER_PORT);
|
||||
|
||||
#ifdef HAVE_IPV6
|
||||
if (src)
|
||||
family = src->sa.sa_family;
|
||||
else
|
||||
family = dst->sa.sa_family;
|
||||
|
||||
if (family == AF_INET6)
|
||||
{
|
||||
iphdr = &ip6;
|
||||
ipsz = sizeof(ip6);
|
||||
memset(&ip6, 0, sizeof(ip6));
|
||||
|
||||
ip6.ip6_vfc = 6 << 4;
|
||||
ip6.ip6_plen = htons(sizeof(struct udphdr) + len);
|
||||
ip6.ip6_nxt = IPPROTO_UDP;
|
||||
ip6.ip6_hops = 64;
|
||||
|
||||
if (src)
|
||||
{
|
||||
memcpy(&ip6.ip6_src, &src->in6.sin6_addr, IN6ADDRSZ);
|
||||
udp.uh_sport = src->in6.sin6_port;
|
||||
}
|
||||
|
||||
if (dst)
|
||||
{
|
||||
memcpy(&ip6.ip6_dst, &dst->in6.sin6_addr, IN6ADDRSZ);
|
||||
udp.uh_dport = dst->in6.sin6_port;
|
||||
}
|
||||
|
||||
/* start UDP checksum */
|
||||
for (sum = 0, i = 0; i < IN6ADDRSZ; i++)
|
||||
sum += ((u16 *)&ip6.ip6_src)[i];
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
iphdr = &ip;
|
||||
ipsz = sizeof(ip);
|
||||
memset(&ip, 0, sizeof(ip));
|
||||
|
||||
ip.ip_v = IPVERSION;
|
||||
ip.ip_hl = sizeof(struct ip) / 4;
|
||||
ip.ip_len = htons(sizeof(struct ip) + sizeof(struct udphdr) + len);
|
||||
ip.ip_ttl = IPDEFTTL;
|
||||
ip.ip_p = IPPROTO_UDP;
|
||||
|
||||
if (src)
|
||||
{
|
||||
ip.ip_src = src->in.sin_addr;
|
||||
udp.uh_sport = src->in.sin_port;
|
||||
}
|
||||
|
||||
if (dst)
|
||||
{
|
||||
ip.ip_dst = dst->in.sin_addr;
|
||||
udp.uh_dport = dst->in.sin_port;
|
||||
}
|
||||
|
||||
ip.ip_sum = 0;
|
||||
for (sum = 0, i = 0; i < sizeof(struct ip) / 2; i++)
|
||||
sum += ((u16 *)&ip)[i];
|
||||
while (sum >> 16)
|
||||
sum = (sum & 0xffff) + (sum >> 16);
|
||||
ip.ip_sum = (sum == 0xffff) ? sum : ~sum;
|
||||
|
||||
/* start UDP checksum */
|
||||
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;
|
||||
}
|
||||
|
||||
if (len & 1)
|
||||
((unsigned char *)packet)[len] = 0; /* for checksum, in case length is odd. */
|
||||
|
||||
udp.uh_sum = 0;
|
||||
udp.uh_ulen = htons(sizeof(struct udphdr) + len);
|
||||
sum += htons(IPPROTO_UDP);
|
||||
sum += htons(sizeof(struct udphdr) + len);
|
||||
for (i = 0; i < sizeof(struct udphdr)/2; i++)
|
||||
sum += ((u16 *)&udp)[i];
|
||||
for (i = 0; i < (len + 1) / 2; i++)
|
||||
sum += ((u16 *)packet)[i];
|
||||
while (sum >> 16)
|
||||
sum = (sum & 0xffff) + (sum >> 16);
|
||||
udp.uh_sum = (sum == 0xffff) ? sum : ~sum;
|
||||
|
||||
rc = gettimeofday(&time, NULL);
|
||||
pcap_header.ts_sec = time.tv_sec;
|
||||
pcap_header.ts_usec = time.tv_usec;
|
||||
pcap_header.incl_len = pcap_header.orig_len = ipsz + sizeof(udp) + len;
|
||||
|
||||
if (rc == -1 ||
|
||||
!read_write(daemon->dumpfd, (void *)&pcap_header, sizeof(pcap_header), 0) ||
|
||||
!read_write(daemon->dumpfd, iphdr, ipsz, 0) ||
|
||||
!read_write(daemon->dumpfd, (void *)&udp, sizeof(udp), 0) ||
|
||||
!read_write(daemon->dumpfd, (void *)packet, len, 0))
|
||||
my_syslog(LOG_ERR, _("failed to write packet dump"));
|
||||
else
|
||||
my_syslog(LOG_INFO, _("dumping UDP packet %u mask 0x%04x"), ++packet_count, mask);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
449
src/edns0.c
Normal file
449
src/edns0.c
Normal file
@@ -0,0 +1,449 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2018 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"
|
||||
|
||||
unsigned char *find_pseudoheader(struct dns_header *header, size_t plen, size_t *len, unsigned char **p, int *is_sign, int *is_last)
|
||||
{
|
||||
/* See if packet has an RFC2671 pseudoheader, and if so return a pointer to it.
|
||||
also return length of pseudoheader in *len and pointer to the UDP size in *p
|
||||
Finally, check to see if a packet is signed. If it is we cannot change a single bit before
|
||||
forwarding. We look for TSIG in the addition section, and TKEY queries (for GSS-TSIG) */
|
||||
|
||||
int i, arcount = ntohs(header->arcount);
|
||||
unsigned char *ansp = (unsigned char *)(header+1);
|
||||
unsigned short rdlen, type, class;
|
||||
unsigned char *ret = NULL;
|
||||
|
||||
if (is_sign)
|
||||
{
|
||||
*is_sign = 0;
|
||||
|
||||
if (OPCODE(header) == QUERY)
|
||||
{
|
||||
for (i = ntohs(header->qdcount); i != 0; i--)
|
||||
{
|
||||
if (!(ansp = skip_name(ansp, header, plen, 4)))
|
||||
return NULL;
|
||||
|
||||
GETSHORT(type, ansp);
|
||||
GETSHORT(class, ansp);
|
||||
|
||||
if (class == C_IN && type == T_TKEY)
|
||||
*is_sign = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(ansp = skip_questions(header, plen)))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (arcount == 0)
|
||||
return NULL;
|
||||
|
||||
if (!(ansp = skip_section(ansp, ntohs(header->ancount) + ntohs(header->nscount), header, plen)))
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < arcount; i++)
|
||||
{
|
||||
unsigned char *save, *start = ansp;
|
||||
if (!(ansp = skip_name(ansp, header, plen, 10)))
|
||||
return NULL;
|
||||
|
||||
GETSHORT(type, ansp);
|
||||
save = ansp;
|
||||
GETSHORT(class, ansp);
|
||||
ansp += 4; /* TTL */
|
||||
GETSHORT(rdlen, ansp);
|
||||
if (!ADD_RDLEN(header, ansp, plen, rdlen))
|
||||
return NULL;
|
||||
if (type == T_OPT)
|
||||
{
|
||||
if (len)
|
||||
*len = ansp - start;
|
||||
|
||||
if (p)
|
||||
*p = save;
|
||||
|
||||
if (is_last)
|
||||
*is_last = (i == arcount-1);
|
||||
|
||||
ret = start;
|
||||
}
|
||||
else if (is_sign &&
|
||||
i == arcount - 1 &&
|
||||
class == C_ANY &&
|
||||
type == T_TSIG)
|
||||
*is_sign = 1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* replace == 2 ->delete existing option only. */
|
||||
size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *limit,
|
||||
unsigned short udp_sz, int optno, unsigned char *opt, size_t optlen, int set_do, int replace)
|
||||
{
|
||||
unsigned char *lenp, *datap, *p, *udp_len, *buff = NULL;
|
||||
int rdlen = 0, is_sign, is_last;
|
||||
unsigned short flags = set_do ? 0x8000 : 0, rcode = 0;
|
||||
|
||||
p = find_pseudoheader(header, plen, NULL, &udp_len, &is_sign, &is_last);
|
||||
|
||||
if (is_sign)
|
||||
return plen;
|
||||
|
||||
if (p)
|
||||
{
|
||||
/* Existing header */
|
||||
int i;
|
||||
unsigned short code, len;
|
||||
|
||||
p = udp_len;
|
||||
GETSHORT(udp_sz, p);
|
||||
GETSHORT(rcode, p);
|
||||
GETSHORT(flags, p);
|
||||
|
||||
if (set_do)
|
||||
{
|
||||
p -= 2;
|
||||
flags |= 0x8000;
|
||||
PUTSHORT(flags, p);
|
||||
}
|
||||
|
||||
lenp = p;
|
||||
GETSHORT(rdlen, p);
|
||||
if (!CHECK_LEN(header, p, plen, rdlen))
|
||||
return plen; /* bad packet */
|
||||
datap = p;
|
||||
|
||||
/* no option to add */
|
||||
if (optno == 0)
|
||||
return plen;
|
||||
|
||||
/* check if option already there */
|
||||
for (i = 0; i + 4 < rdlen;)
|
||||
{
|
||||
GETSHORT(code, p);
|
||||
GETSHORT(len, p);
|
||||
|
||||
/* malformed option, delete the whole OPT RR and start again. */
|
||||
if (i + 4 + len > rdlen)
|
||||
{
|
||||
rdlen = 0;
|
||||
is_last = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (code == optno)
|
||||
{
|
||||
if (replace == 0)
|
||||
return plen;
|
||||
|
||||
/* delete option if we're to replace it. */
|
||||
p -= 4;
|
||||
rdlen -= len + 4;
|
||||
memmove(p, p+len+4, rdlen - i);
|
||||
PUTSHORT(rdlen, lenp);
|
||||
lenp -= 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
p += len;
|
||||
i += len + 4;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we're going to extend the RR, it has to be the last RR in the packet */
|
||||
if (!is_last)
|
||||
{
|
||||
/* First, take a copy of the options. */
|
||||
if (rdlen != 0 && (buff = whine_malloc(rdlen)))
|
||||
memcpy(buff, datap, rdlen);
|
||||
|
||||
/* now, delete OPT RR */
|
||||
plen = rrfilter(header, plen, 0);
|
||||
|
||||
/* Now, force addition of a new one */
|
||||
p = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!p)
|
||||
{
|
||||
/* We are (re)adding the pseudoheader */
|
||||
if (!(p = skip_questions(header, plen)) ||
|
||||
!(p = skip_section(p,
|
||||
ntohs(header->ancount) + ntohs(header->nscount) + ntohs(header->arcount),
|
||||
header, plen)))
|
||||
{
|
||||
free(buff);
|
||||
return plen;
|
||||
}
|
||||
if (p + 11 > limit)
|
||||
{
|
||||
free(buff);
|
||||
return plen; /* Too big */
|
||||
}
|
||||
*p++ = 0; /* empty name */
|
||||
PUTSHORT(T_OPT, p);
|
||||
PUTSHORT(udp_sz, p); /* max packet length, 512 if not given in EDNS0 header */
|
||||
PUTSHORT(rcode, p); /* extended RCODE and version */
|
||||
PUTSHORT(flags, p); /* DO flag */
|
||||
lenp = p;
|
||||
PUTSHORT(rdlen, p); /* RDLEN */
|
||||
datap = p;
|
||||
/* Copy back any options */
|
||||
if (buff)
|
||||
{
|
||||
if (p + rdlen > limit)
|
||||
{
|
||||
free(buff);
|
||||
return plen; /* Too big */
|
||||
}
|
||||
memcpy(p, buff, rdlen);
|
||||
free(buff);
|
||||
p += rdlen;
|
||||
}
|
||||
|
||||
/* Only bump arcount if RR is going to fit */
|
||||
if (((ssize_t)optlen) <= (limit - (p + 4)))
|
||||
header->arcount = htons(ntohs(header->arcount) + 1);
|
||||
}
|
||||
|
||||
if (((ssize_t)optlen) > (limit - (p + 4)))
|
||||
return plen; /* Too big */
|
||||
|
||||
/* Add new option */
|
||||
if (optno != 0 && replace != 2)
|
||||
{
|
||||
if (p + 4 > limit)
|
||||
return plen; /* Too big */
|
||||
PUTSHORT(optno, p);
|
||||
PUTSHORT(optlen, p);
|
||||
if (p + optlen > limit)
|
||||
return plen; /* Too big */
|
||||
memcpy(p, opt, optlen);
|
||||
p += optlen;
|
||||
PUTSHORT(p - datap, lenp);
|
||||
}
|
||||
return p - (unsigned char *)header;
|
||||
}
|
||||
|
||||
size_t add_do_bit(struct dns_header *header, size_t plen, unsigned char *limit)
|
||||
{
|
||||
return add_pseudoheader(header, plen, (unsigned char *)limit, PACKETSZ, 0, NULL, 0, 1, 0);
|
||||
}
|
||||
|
||||
static unsigned char char64(unsigned char c)
|
||||
{
|
||||
return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[c & 0x3f];
|
||||
}
|
||||
|
||||
static void encoder(unsigned char *in, char *out)
|
||||
{
|
||||
out[0] = char64(in[0]>>2);
|
||||
out[1] = char64((in[0]<<4) | (in[1]>>4));
|
||||
out[2] = char64((in[1]<<2) | (in[2]>>6));
|
||||
out[3] = char64(in[2]);
|
||||
}
|
||||
|
||||
static size_t add_dns_client(struct dns_header *header, size_t plen, unsigned char *limit, union mysockaddr *l3, time_t now)
|
||||
{
|
||||
int maclen, replace = 2; /* can't get mac address, just delete any incoming. */
|
||||
unsigned char mac[DHCP_CHADDR_MAX];
|
||||
char encode[18]; /* handle 6 byte MACs */
|
||||
|
||||
if ((maclen = find_mac(l3, mac, 1, now)) == 6)
|
||||
{
|
||||
replace = 1;
|
||||
|
||||
if (option_bool(OPT_MAC_HEX))
|
||||
print_mac(encode, mac, maclen);
|
||||
else
|
||||
{
|
||||
encoder(mac, encode);
|
||||
encoder(mac+3, encode+4);
|
||||
encode[8] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return add_pseudoheader(header, plen, limit, PACKETSZ, EDNS0_OPTION_NOMDEVICEID, (unsigned char *)encode, strlen(encode), 0, replace);
|
||||
}
|
||||
|
||||
|
||||
static size_t add_mac(struct dns_header *header, size_t plen, unsigned char *limit, union mysockaddr *l3, time_t now)
|
||||
{
|
||||
int maclen;
|
||||
unsigned char mac[DHCP_CHADDR_MAX];
|
||||
|
||||
if ((maclen = find_mac(l3, mac, 1, now)) != 0)
|
||||
plen = add_pseudoheader(header, plen, limit, PACKETSZ, EDNS0_OPTION_MAC, mac, maclen, 0, 0);
|
||||
|
||||
return plen;
|
||||
}
|
||||
|
||||
struct subnet_opt {
|
||||
u16 family;
|
||||
u8 source_netmask, scope_netmask;
|
||||
#ifdef HAVE_IPV6
|
||||
u8 addr[IN6ADDRSZ];
|
||||
#else
|
||||
u8 addr[INADDRSZ];
|
||||
#endif
|
||||
};
|
||||
|
||||
static void *get_addrp(union mysockaddr *addr, const short family)
|
||||
{
|
||||
#ifdef HAVE_IPV6
|
||||
if (family == AF_INET6)
|
||||
return &addr->in6.sin6_addr;
|
||||
#endif
|
||||
|
||||
return &addr->in.sin_addr;
|
||||
}
|
||||
|
||||
static size_t calc_subnet_opt(struct subnet_opt *opt, union mysockaddr *source)
|
||||
{
|
||||
/* http://tools.ietf.org/html/draft-vandergaast-edns-client-subnet-02 */
|
||||
|
||||
int len;
|
||||
void *addrp = NULL;
|
||||
int sa_family = source->sa.sa_family;
|
||||
|
||||
opt->source_netmask = 0;
|
||||
opt->scope_netmask = 0;
|
||||
|
||||
#ifdef HAVE_IPV6
|
||||
if (source->sa.sa_family == AF_INET6 && daemon->add_subnet6)
|
||||
{
|
||||
opt->source_netmask = daemon->add_subnet6->mask;
|
||||
if (daemon->add_subnet6->addr_used)
|
||||
{
|
||||
sa_family = daemon->add_subnet6->addr.sa.sa_family;
|
||||
addrp = get_addrp(&daemon->add_subnet6->addr, sa_family);
|
||||
}
|
||||
else
|
||||
addrp = &source->in6.sin6_addr;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (source->sa.sa_family == AF_INET && daemon->add_subnet4)
|
||||
{
|
||||
opt->source_netmask = daemon->add_subnet4->mask;
|
||||
if (daemon->add_subnet4->addr_used)
|
||||
{
|
||||
sa_family = daemon->add_subnet4->addr.sa.sa_family;
|
||||
addrp = get_addrp(&daemon->add_subnet4->addr, sa_family);
|
||||
}
|
||||
else
|
||||
addrp = &source->in.sin_addr;
|
||||
}
|
||||
|
||||
#ifdef HAVE_IPV6
|
||||
opt->family = htons(sa_family == AF_INET6 ? 2 : 1);
|
||||
#else
|
||||
opt->family = htons(1);
|
||||
#endif
|
||||
|
||||
len = 0;
|
||||
|
||||
if (addrp && opt->source_netmask != 0)
|
||||
{
|
||||
len = ((opt->source_netmask - 1) >> 3) + 1;
|
||||
memcpy(opt->addr, addrp, len);
|
||||
if (opt->source_netmask & 7)
|
||||
opt->addr[len-1] &= 0xff << (8 - (opt->source_netmask & 7));
|
||||
}
|
||||
|
||||
return len + 4;
|
||||
}
|
||||
|
||||
static size_t add_source_addr(struct dns_header *header, size_t plen, unsigned char *limit, union mysockaddr *source)
|
||||
{
|
||||
/* http://tools.ietf.org/html/draft-vandergaast-edns-client-subnet-02 */
|
||||
|
||||
int len;
|
||||
struct subnet_opt opt;
|
||||
|
||||
len = calc_subnet_opt(&opt, source);
|
||||
return add_pseudoheader(header, plen, (unsigned char *)limit, PACKETSZ, EDNS0_OPTION_CLIENT_SUBNET, (unsigned char *)&opt, len, 0, 0);
|
||||
}
|
||||
|
||||
int check_source(struct dns_header *header, size_t plen, unsigned char *pseudoheader, union mysockaddr *peer)
|
||||
{
|
||||
/* Section 9.2, Check that subnet option in reply matches. */
|
||||
|
||||
int len, calc_len;
|
||||
struct subnet_opt opt;
|
||||
unsigned char *p;
|
||||
int code, i, rdlen;
|
||||
|
||||
calc_len = calc_subnet_opt(&opt, peer);
|
||||
|
||||
if (!(p = skip_name(pseudoheader, header, plen, 10)))
|
||||
return 1;
|
||||
|
||||
p += 8; /* skip UDP length and RCODE */
|
||||
|
||||
GETSHORT(rdlen, p);
|
||||
if (!CHECK_LEN(header, p, plen, rdlen))
|
||||
return 1; /* bad packet */
|
||||
|
||||
/* check if option there */
|
||||
for (i = 0; i + 4 < rdlen; i += len + 4)
|
||||
{
|
||||
GETSHORT(code, p);
|
||||
GETSHORT(len, p);
|
||||
if (code == EDNS0_OPTION_CLIENT_SUBNET)
|
||||
{
|
||||
/* make sure this doesn't mismatch. */
|
||||
opt.scope_netmask = p[3];
|
||||
if (len != calc_len || memcmp(p, &opt, len) != 0)
|
||||
return 0;
|
||||
}
|
||||
p += len;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t add_edns0_config(struct dns_header *header, size_t plen, unsigned char *limit,
|
||||
union mysockaddr *source, time_t now, int *check_subnet)
|
||||
{
|
||||
*check_subnet = 0;
|
||||
|
||||
if (option_bool(OPT_ADD_MAC))
|
||||
plen = add_mac(header, plen, limit, source, now);
|
||||
|
||||
if (option_bool(OPT_MAC_B64) || option_bool(OPT_MAC_HEX))
|
||||
plen = add_dns_client(header, plen, limit, source, now);
|
||||
|
||||
if (daemon->dns_client_id)
|
||||
plen = add_pseudoheader(header, plen, limit, PACKETSZ, EDNS0_OPTION_NOMCPEID,
|
||||
(unsigned char *)daemon->dns_client_id, strlen(daemon->dns_client_id), 0, 1);
|
||||
|
||||
if (option_bool(OPT_CLIENT_SUBNET))
|
||||
{
|
||||
plen = add_source_addr(header, plen, limit, source);
|
||||
*check_subnet = 1;
|
||||
}
|
||||
|
||||
return plen;
|
||||
}
|
||||
1334
src/forward.c
1334
src/forward.c
File diff suppressed because it is too large
Load Diff
125
src/helper.c
125
src/helper.c
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2014 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2018 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
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
#ifdef HAVE_SCRIPT
|
||||
|
||||
/* This file has code to fork a helper process which recieves data via a pipe
|
||||
/* This file has code to fork a helper process which receives data via a pipe
|
||||
shared with the main process and which is responsible for calling a script when
|
||||
DHCP leases change.
|
||||
|
||||
@@ -97,13 +97,14 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
|
||||
return pipefd[1];
|
||||
}
|
||||
|
||||
/* ignore SIGTERM, so that we can clean up when the main process gets hit
|
||||
/* ignore SIGTERM and SIGINT, so that we can clean up when the main process gets hit
|
||||
and SIGALRM so that we can use sleep() */
|
||||
sigact.sa_handler = SIG_IGN;
|
||||
sigact.sa_flags = 0;
|
||||
sigemptyset(&sigact.sa_mask);
|
||||
sigaction(SIGTERM, &sigact, NULL);
|
||||
sigaction(SIGALRM, &sigact, NULL);
|
||||
sigaction(SIGINT, &sigact, NULL);
|
||||
|
||||
if (!option_bool(OPT_DEBUG) && uid != 0)
|
||||
{
|
||||
@@ -135,7 +136,7 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
|
||||
max_fd != STDIN_FILENO && max_fd != pipefd[0] &&
|
||||
max_fd != event_fd && max_fd != err_fd)
|
||||
close(max_fd);
|
||||
|
||||
|
||||
#ifdef HAVE_LUASCRIPT
|
||||
if (daemon->luascript)
|
||||
{
|
||||
@@ -189,6 +190,7 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
|
||||
unsigned char *buf = (unsigned char *)daemon->namebuff;
|
||||
unsigned char *end, *extradata, *alloc_buff = NULL;
|
||||
int is6, err = 0;
|
||||
int pipeout[2];
|
||||
|
||||
free(alloc_buff);
|
||||
|
||||
@@ -219,7 +221,18 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
|
||||
action_str = "tftp";
|
||||
is6 = (data.flags != AF_INET);
|
||||
}
|
||||
else
|
||||
else if (data.action == ACTION_ARP)
|
||||
{
|
||||
action_str = "arp-add";
|
||||
is6 = (data.flags != AF_INET);
|
||||
}
|
||||
else if (data.action == ACTION_ARP_DEL)
|
||||
{
|
||||
action_str = "arp-del";
|
||||
is6 = (data.flags != AF_INET);
|
||||
data.action = ACTION_ARP;
|
||||
}
|
||||
else
|
||||
continue;
|
||||
|
||||
|
||||
@@ -289,7 +302,7 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
|
||||
|
||||
if (!is6)
|
||||
inet_ntop(AF_INET, &data.addr, daemon->addrbuff, ADDRSTRLEN);
|
||||
#ifdef HAVE_DHCP6
|
||||
#ifdef HAVE_IPV6
|
||||
else
|
||||
inet_ntop(AF_INET6, &data.addr6, daemon->addrbuff, ADDRSTRLEN);
|
||||
#endif
|
||||
@@ -321,6 +334,22 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
|
||||
lua_call(lua, 2, 0); /* pass 2 values, expect 0 */
|
||||
}
|
||||
}
|
||||
else if (data.action == ACTION_ARP)
|
||||
{
|
||||
lua_getglobal(lua, "arp");
|
||||
if (lua_type(lua, -1) != LUA_TFUNCTION)
|
||||
lua_pop(lua, 1); /* arp function optional */
|
||||
else
|
||||
{
|
||||
lua_pushstring(lua, action_str); /* arg1 - action */
|
||||
lua_newtable(lua); /* arg2 - data table */
|
||||
lua_pushstring(lua, daemon->addrbuff);
|
||||
lua_setfield(lua, -2, "client_address");
|
||||
lua_pushstring(lua, daemon->dhcp_buff);
|
||||
lua_setfield(lua, -2, "mac_address");
|
||||
lua_call(lua, 2, 0); /* pass 2 values, expect 0 */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_getglobal(lua, "lease"); /* function to call */
|
||||
@@ -445,16 +474,54 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
|
||||
if (!daemon->lease_change_command)
|
||||
continue;
|
||||
|
||||
/* Pipe to capture stdout and stderr from script */
|
||||
if (!option_bool(OPT_DEBUG) && pipe(pipeout) == -1)
|
||||
continue;
|
||||
|
||||
/* possible fork errors are all temporary resource problems */
|
||||
while ((pid = fork()) == -1 && (errno == EAGAIN || errno == ENOMEM))
|
||||
sleep(2);
|
||||
|
||||
if (pid == -1)
|
||||
continue;
|
||||
{
|
||||
if (!option_bool(OPT_DEBUG))
|
||||
{
|
||||
close(pipeout[0]);
|
||||
close(pipeout[1]);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/* wait for child to complete */
|
||||
if (pid != 0)
|
||||
{
|
||||
if (!option_bool(OPT_DEBUG))
|
||||
{
|
||||
FILE *fp;
|
||||
|
||||
close(pipeout[1]);
|
||||
|
||||
/* Read lines sent to stdout/err by the script and pass them back to be logged */
|
||||
if (!(fp = fdopen(pipeout[0], "r")))
|
||||
close(pipeout[0]);
|
||||
else
|
||||
{
|
||||
while (fgets(daemon->packet, daemon->packet_buff_sz, fp))
|
||||
{
|
||||
/* do not include new lines, log will append them */
|
||||
size_t len = strlen(daemon->packet);
|
||||
if (len > 0)
|
||||
{
|
||||
--len;
|
||||
if (daemon->packet[len] == '\n')
|
||||
daemon->packet[len] = 0;
|
||||
}
|
||||
send_event(event_fd, EVENT_SCRIPT_LOG, 0, daemon->packet);
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
/* reap our children's children, if necessary */
|
||||
while (1)
|
||||
{
|
||||
@@ -477,8 +544,17 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!option_bool(OPT_DEBUG))
|
||||
{
|
||||
/* map stdout/stderr of script to pipeout */
|
||||
close(pipeout[0]);
|
||||
dup2(pipeout[1], STDOUT_FILENO);
|
||||
dup2(pipeout[1], STDERR_FILENO);
|
||||
close(pipeout[1]);
|
||||
}
|
||||
|
||||
if (data.action != ACTION_TFTP)
|
||||
if (data.action != ACTION_TFTP && data.action != ACTION_ARP)
|
||||
{
|
||||
#ifdef HAVE_DHCP6
|
||||
my_setenv("DNSMASQ_IAID", is6 ? daemon->dhcp_buff3 : NULL, &err);
|
||||
@@ -529,6 +605,7 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
|
||||
buf = grab_extradata(buf, end, "DNSMASQ_CIRCUIT_ID", &err);
|
||||
buf = grab_extradata(buf, end, "DNSMASQ_SUBSCRIBER_ID", &err);
|
||||
buf = grab_extradata(buf, end, "DNSMASQ_REMOTE_ID", &err);
|
||||
buf = grab_extradata(buf, end, "DNSMASQ_REQUESTED_OPTIONS", &err);
|
||||
}
|
||||
|
||||
buf = grab_extradata(buf, end, "DNSMASQ_TAGS", &err);
|
||||
@@ -550,9 +627,9 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
|
||||
my_setenv("DNSMASQ_OLD_HOSTNAME", data.action == ACTION_OLD_HOSTNAME ? hostname : NULL, &err);
|
||||
if (data.action == ACTION_OLD_HOSTNAME)
|
||||
hostname = NULL;
|
||||
|
||||
my_setenv("DNSMASQ_LOG_DHCP", option_bool(OPT_LOG_OPTS) ? "1" : NULL, &err);
|
||||
}
|
||||
|
||||
my_setenv("DNSMASQ_LOG_DHCP", option_bool(OPT_LOG_OPTS) ? "1" : NULL, &err);
|
||||
|
||||
/* we need to have the event_fd around if exec fails */
|
||||
if ((i = fcntl(event_fd, F_GETFD)) != -1)
|
||||
@@ -563,8 +640,8 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
|
||||
if (err == 0)
|
||||
{
|
||||
execl(daemon->lease_change_command,
|
||||
p ? p+1 : daemon->lease_change_command,
|
||||
action_str, is6 ? daemon->packet : daemon->dhcp_buff,
|
||||
p ? p+1 : daemon->lease_change_command, action_str,
|
||||
(is6 && data.action != ACTION_ARP) ? daemon->packet : daemon->dhcp_buff,
|
||||
daemon->addrbuff, hostname, (char*)NULL);
|
||||
err = errno;
|
||||
}
|
||||
@@ -760,6 +837,30 @@ void queue_tftp(off_t file_len, char *filename, union mysockaddr *peer)
|
||||
}
|
||||
#endif
|
||||
|
||||
void queue_arp(int action, unsigned char *mac, int maclen, int family, struct all_addr *addr)
|
||||
{
|
||||
/* no script */
|
||||
if (daemon->helperfd == -1)
|
||||
return;
|
||||
|
||||
buff_alloc(sizeof(struct script_data));
|
||||
memset(buf, 0, sizeof(struct script_data));
|
||||
|
||||
buf->action = action;
|
||||
buf->hwaddr_len = maclen;
|
||||
buf->hwaddr_type = ARPHRD_ETHER;
|
||||
if ((buf->flags = family) == AF_INET)
|
||||
buf->addr = addr->addr.addr4;
|
||||
#ifdef HAVE_IPV6
|
||||
else
|
||||
buf->addr6 = addr->addr.addr6;
|
||||
#endif
|
||||
|
||||
memcpy(buf->hwaddr, mac, maclen);
|
||||
|
||||
bytes_in_buf = sizeof(struct script_data);
|
||||
}
|
||||
|
||||
int helper_buf_empty(void)
|
||||
{
|
||||
return bytes_in_buf == 0;
|
||||
|
||||
298
src/inotify.c
Normal file
298
src/inotify.c
Normal file
@@ -0,0 +1,298 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2018 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_INOTIFY
|
||||
|
||||
#include <sys/inotify.h>
|
||||
#include <sys/param.h> /* For MAXSYMLINKS */
|
||||
|
||||
/* the strategy is to set an inotify on the directories containing
|
||||
resolv files, for any files in the directory which are close-write
|
||||
or moved into the directory.
|
||||
|
||||
When either of those happen, we look to see if the file involved
|
||||
is actually a resolv-file, and if so, call poll-resolv with
|
||||
the "force" argument, to ensure it's read.
|
||||
|
||||
This adds one new error condition: the directories containing
|
||||
all specified resolv-files must exist at start-up, even if the actual
|
||||
files don't.
|
||||
*/
|
||||
|
||||
static char *inotify_buffer;
|
||||
#define INOTIFY_SZ (sizeof(struct inotify_event) + NAME_MAX + 1)
|
||||
|
||||
/* If path is a symbolic link, return the path it
|
||||
points to, made absolute if relative.
|
||||
If path doesn't exist or is not a symlink, return NULL.
|
||||
Return value is malloc'ed */
|
||||
static char *my_readlink(char *path)
|
||||
{
|
||||
ssize_t rc, size = 64;
|
||||
char *buf;
|
||||
|
||||
while (1)
|
||||
{
|
||||
buf = safe_malloc(size);
|
||||
rc = readlink(path, buf, (size_t)size);
|
||||
|
||||
if (rc == -1)
|
||||
{
|
||||
/* Not link or doesn't exist. */
|
||||
if (errno == EINVAL || errno == ENOENT)
|
||||
{
|
||||
free(buf);
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
die(_("cannot access path %s: %s"), path, EC_MISC);
|
||||
}
|
||||
else if (rc < size-1)
|
||||
{
|
||||
char *d;
|
||||
|
||||
buf[rc] = 0;
|
||||
if (buf[0] != '/' && ((d = strrchr(path, '/'))))
|
||||
{
|
||||
/* Add path to relative link */
|
||||
char *new_buf = safe_malloc((d - path) + strlen(buf) + 2);
|
||||
*(d+1) = 0;
|
||||
strcpy(new_buf, path);
|
||||
strcat(new_buf, buf);
|
||||
free(buf);
|
||||
buf = new_buf;
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* Buffer too small, increase and retry */
|
||||
size += 64;
|
||||
free(buf);
|
||||
}
|
||||
}
|
||||
|
||||
void inotify_dnsmasq_init()
|
||||
{
|
||||
struct resolvc *res;
|
||||
inotify_buffer = safe_malloc(INOTIFY_SZ);
|
||||
daemon->inotifyfd = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
|
||||
|
||||
if (daemon->inotifyfd == -1)
|
||||
die(_("failed to create inotify: %s"), NULL, EC_MISC);
|
||||
|
||||
if (option_bool(OPT_NO_RESOLV))
|
||||
return;
|
||||
|
||||
for (res = daemon->resolv_files; res; res = res->next)
|
||||
{
|
||||
char *d, *new_path, *path = safe_malloc(strlen(res->name) + 1);
|
||||
int links = MAXSYMLINKS;
|
||||
|
||||
strcpy(path, res->name);
|
||||
|
||||
/* Follow symlinks until we reach a non-symlink, or a non-existent file. */
|
||||
while ((new_path = my_readlink(path)))
|
||||
{
|
||||
if (links-- == 0)
|
||||
die(_("too many symlinks following %s"), res->name, EC_MISC);
|
||||
free(path);
|
||||
path = new_path;
|
||||
}
|
||||
|
||||
res->wd = -1;
|
||||
|
||||
if ((d = strrchr(path, '/')))
|
||||
{
|
||||
*d = 0; /* make path just directory */
|
||||
res->wd = inotify_add_watch(daemon->inotifyfd, path, IN_CLOSE_WRITE | IN_MOVED_TO);
|
||||
|
||||
res->file = d+1; /* pointer to filename */
|
||||
*d = '/';
|
||||
|
||||
if (res->wd == -1 && errno == ENOENT)
|
||||
die(_("directory %s for resolv-file is missing, cannot poll"), res->name, EC_MISC);
|
||||
}
|
||||
|
||||
if (res->wd == -1)
|
||||
die(_("failed to create inotify for %s: %s"), res->name, EC_MISC);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* initialisation for dynamic-dir. Set inotify watch for each directory, and read pre-existing files */
|
||||
void set_dynamic_inotify(int flag, int total_size, struct crec **rhash, int revhashsz)
|
||||
{
|
||||
struct hostsfile *ah;
|
||||
|
||||
for (ah = daemon->dynamic_dirs; ah; ah = ah->next)
|
||||
{
|
||||
DIR *dir_stream = NULL;
|
||||
struct dirent *ent;
|
||||
struct stat buf;
|
||||
|
||||
if (!(ah->flags & flag))
|
||||
continue;
|
||||
|
||||
if (stat(ah->fname, &buf) == -1 || !(S_ISDIR(buf.st_mode)))
|
||||
{
|
||||
my_syslog(LOG_ERR, _("bad dynamic directory %s: %s"),
|
||||
ah->fname, strerror(errno));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(ah->flags & AH_WD_DONE))
|
||||
{
|
||||
ah->wd = inotify_add_watch(daemon->inotifyfd, ah->fname, IN_CLOSE_WRITE | IN_MOVED_TO);
|
||||
ah->flags |= AH_WD_DONE;
|
||||
}
|
||||
|
||||
/* Read contents of dir _after_ calling add_watch, in the hope of avoiding
|
||||
a race which misses files being added as we start */
|
||||
if (ah->wd == -1 || !(dir_stream = opendir(ah->fname)))
|
||||
{
|
||||
my_syslog(LOG_ERR, _("failed to create inotify for %s: %s"),
|
||||
ah->fname, strerror(errno));
|
||||
continue;
|
||||
}
|
||||
|
||||
while ((ent = readdir(dir_stream)))
|
||||
{
|
||||
size_t lendir = strlen(ah->fname);
|
||||
size_t lenfile = strlen(ent->d_name);
|
||||
char *path;
|
||||
|
||||
/* ignore emacs backups and dotfiles */
|
||||
if (lenfile == 0 ||
|
||||
ent->d_name[lenfile - 1] == '~' ||
|
||||
(ent->d_name[0] == '#' && ent->d_name[lenfile - 1] == '#') ||
|
||||
ent->d_name[0] == '.')
|
||||
continue;
|
||||
|
||||
if ((path = whine_malloc(lendir + lenfile + 2)))
|
||||
{
|
||||
strcpy(path, ah->fname);
|
||||
strcat(path, "/");
|
||||
strcat(path, ent->d_name);
|
||||
|
||||
/* ignore non-regular files */
|
||||
if (stat(path, &buf) != -1 && S_ISREG(buf.st_mode))
|
||||
{
|
||||
if (ah->flags & AH_HOSTS)
|
||||
total_size = read_hostsfile(path, ah->index, total_size, rhash, revhashsz);
|
||||
#ifdef HAVE_DHCP
|
||||
else if (ah->flags & (AH_DHCP_HST | AH_DHCP_OPT))
|
||||
option_read_dynfile(path, ah->flags);
|
||||
#endif
|
||||
}
|
||||
|
||||
free(path);
|
||||
}
|
||||
}
|
||||
|
||||
closedir(dir_stream);
|
||||
}
|
||||
}
|
||||
|
||||
int inotify_check(time_t now)
|
||||
{
|
||||
int hit = 0;
|
||||
struct hostsfile *ah;
|
||||
|
||||
while (1)
|
||||
{
|
||||
int rc;
|
||||
char *p;
|
||||
struct resolvc *res;
|
||||
struct inotify_event *in;
|
||||
|
||||
while ((rc = read(daemon->inotifyfd, inotify_buffer, INOTIFY_SZ)) == -1 && errno == EINTR);
|
||||
|
||||
if (rc <= 0)
|
||||
break;
|
||||
|
||||
for (p = inotify_buffer; rc - (p - inotify_buffer) >= (int)sizeof(struct inotify_event); p += sizeof(struct inotify_event) + in->len)
|
||||
{
|
||||
size_t namelen;
|
||||
|
||||
in = (struct inotify_event*)p;
|
||||
|
||||
/* ignore emacs backups and dotfiles */
|
||||
if (in->len == 0 || (namelen = strlen(in->name)) == 0 ||
|
||||
in->name[namelen - 1] == '~' ||
|
||||
(in->name[0] == '#' && in->name[namelen - 1] == '#') ||
|
||||
in->name[0] == '.')
|
||||
continue;
|
||||
|
||||
for (res = daemon->resolv_files; res; res = res->next)
|
||||
if (res->wd == in->wd && strcmp(res->file, in->name) == 0)
|
||||
hit = 1;
|
||||
|
||||
for (ah = daemon->dynamic_dirs; ah; ah = ah->next)
|
||||
if (ah->wd == in->wd)
|
||||
{
|
||||
size_t lendir = strlen(ah->fname);
|
||||
char *path;
|
||||
|
||||
if ((path = whine_malloc(lendir + in->len + 2)))
|
||||
{
|
||||
strcpy(path, ah->fname);
|
||||
strcat(path, "/");
|
||||
strcat(path, in->name);
|
||||
|
||||
my_syslog(LOG_INFO, _("inotify, new or changed file %s"), path);
|
||||
|
||||
if (ah->flags & AH_HOSTS)
|
||||
{
|
||||
read_hostsfile(path, ah->index, 0, NULL, 0);
|
||||
#ifdef HAVE_DHCP
|
||||
if (daemon->dhcp || daemon->doing_dhcp6)
|
||||
{
|
||||
/* Propagate the consequences of loading a new dhcp-host */
|
||||
dhcp_update_configs(daemon->dhcp_conf);
|
||||
lease_update_from_configs();
|
||||
lease_update_file(now);
|
||||
lease_update_dns(1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#ifdef HAVE_DHCP
|
||||
else if (ah->flags & AH_DHCP_HST)
|
||||
{
|
||||
if (option_read_dynfile(path, AH_DHCP_HST))
|
||||
{
|
||||
/* Propagate the consequences of loading a new dhcp-host */
|
||||
dhcp_update_configs(daemon->dhcp_conf);
|
||||
lease_update_from_configs();
|
||||
lease_update_file(now);
|
||||
lease_update_dns(1);
|
||||
}
|
||||
}
|
||||
else if (ah->flags & AH_DHCP_OPT)
|
||||
option_read_dynfile(path, AH_DHCP_OPT);
|
||||
#endif
|
||||
|
||||
free(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return hit;
|
||||
}
|
||||
|
||||
#endif /* INOTIFY */
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2014 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2018 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
|
||||
|
||||
25
src/ipset.c
25
src/ipset.c
@@ -16,7 +16,7 @@
|
||||
|
||||
#include "dnsmasq.h"
|
||||
|
||||
#ifdef HAVE_IPSET
|
||||
#if defined(HAVE_IPSET) && defined(HAVE_LINUX_NETWORK)
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
@@ -121,7 +121,6 @@ static int new_add_to_ipset(const char *setname, const struct all_addr *ipaddr,
|
||||
struct my_nlattr *nested[2];
|
||||
uint8_t proto;
|
||||
int addrsz = INADDRSZ;
|
||||
ssize_t rc;
|
||||
|
||||
#ifdef HAVE_IPV6
|
||||
if (af == AF_INET6)
|
||||
@@ -162,9 +161,10 @@ static int new_add_to_ipset(const char *setname, const struct all_addr *ipaddr,
|
||||
nested[1]->nla_len = (void *)buffer + NL_ALIGN(nlh->nlmsg_len) - (void *)nested[1];
|
||||
nested[0]->nla_len = (void *)buffer + NL_ALIGN(nlh->nlmsg_len) - (void *)nested[0];
|
||||
|
||||
while ((rc = sendto(ipset_sock, buffer, nlh->nlmsg_len, 0,
|
||||
(struct sockaddr *)&snl, sizeof(snl))) == -1 && retry_send());
|
||||
return rc;
|
||||
while (retry_send(sendto(ipset_sock, buffer, nlh->nlmsg_len, 0,
|
||||
(struct sockaddr *)&snl, sizeof(snl))));
|
||||
|
||||
return errno == 0 ? 0 : -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -211,7 +211,7 @@ static int old_add_to_ipset(const char *setname, const struct all_addr *ipaddr,
|
||||
|
||||
int add_to_ipset(const char *setname, const struct all_addr *ipaddr, int flags, int remove)
|
||||
{
|
||||
int af = AF_INET;
|
||||
int ret = 0, af = AF_INET;
|
||||
|
||||
#ifdef HAVE_IPV6
|
||||
if (flags & F_IPV6)
|
||||
@@ -219,11 +219,20 @@ int add_to_ipset(const char *setname, const struct all_addr *ipaddr, int flags,
|
||||
af = AF_INET6;
|
||||
/* old method only supports IPv4 */
|
||||
if (old_kernel)
|
||||
return -1;
|
||||
{
|
||||
errno = EAFNOSUPPORT ;
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return old_kernel ? old_add_to_ipset(setname, ipaddr, remove) : new_add_to_ipset(setname, ipaddr, af, remove);
|
||||
if (ret != -1)
|
||||
ret = old_kernel ? old_add_to_ipset(setname, ipaddr, remove) : new_add_to_ipset(setname, ipaddr, af, remove);
|
||||
|
||||
if (ret == -1)
|
||||
my_syslog(LOG_ERR, _("failed to update ipset %s: %s"), setname, strerror(errno));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
285
src/lease.c
285
src/lease.c
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2014 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2018 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
|
||||
@@ -21,21 +21,126 @@
|
||||
static struct dhcp_lease *leases = NULL, *old_leases = NULL;
|
||||
static int dns_dirty, file_dirty, leases_left;
|
||||
|
||||
void lease_init(time_t now)
|
||||
static int read_leases(time_t now, FILE *leasestream)
|
||||
{
|
||||
unsigned long ei;
|
||||
struct all_addr addr;
|
||||
struct dhcp_lease *lease;
|
||||
int clid_len, hw_len, hw_type;
|
||||
int items;
|
||||
char *domain = NULL;
|
||||
|
||||
*daemon->dhcp_buff3 = *daemon->dhcp_buff2 = '\0';
|
||||
|
||||
/* client-id max length is 255 which is 255*2 digits + 254 colons
|
||||
borrow DNS packet buffer which is always larger than 1000 bytes
|
||||
|
||||
Check various buffers are big enough for the code below */
|
||||
|
||||
#if (DHCP_BUFF_SZ < 255) || (MAXDNAME < 64) || (PACKETSZ+MAXDNAME+RRFIXEDSZ < 764)
|
||||
# error Buffer size breakage in leasefile parsing.
|
||||
#endif
|
||||
|
||||
while ((items=fscanf(leasestream, "%255s %255s", daemon->dhcp_buff3, daemon->dhcp_buff2)) == 2)
|
||||
{
|
||||
*daemon->namebuff = *daemon->dhcp_buff = *daemon->packet = '\0';
|
||||
hw_len = hw_type = clid_len = 0;
|
||||
|
||||
#ifdef HAVE_DHCP6
|
||||
if (strcmp(daemon->dhcp_buff3, "duid") == 0)
|
||||
{
|
||||
daemon->duid_len = parse_hex(daemon->dhcp_buff2, (unsigned char *)daemon->dhcp_buff2, 130, NULL, NULL);
|
||||
if (daemon->duid_len < 0)
|
||||
return 0;
|
||||
daemon->duid = safe_malloc(daemon->duid_len);
|
||||
memcpy(daemon->duid, daemon->dhcp_buff2, daemon->duid_len);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (fscanf(leasestream, " %64s %255s %764s",
|
||||
daemon->namebuff, daemon->dhcp_buff, daemon->packet) != 3)
|
||||
return 0;
|
||||
|
||||
if (inet_pton(AF_INET, daemon->namebuff, &addr.addr.addr4))
|
||||
{
|
||||
if ((lease = lease4_allocate(addr.addr.addr4)))
|
||||
domain = get_domain(lease->addr);
|
||||
|
||||
hw_len = parse_hex(daemon->dhcp_buff2, (unsigned char *)daemon->dhcp_buff2, DHCP_CHADDR_MAX, NULL, &hw_type);
|
||||
/* For backwards compatibility, no explicit MAC address type means ether. */
|
||||
if (hw_type == 0 && hw_len != 0)
|
||||
hw_type = ARPHRD_ETHER;
|
||||
}
|
||||
#ifdef HAVE_DHCP6
|
||||
else if (inet_pton(AF_INET6, daemon->namebuff, &addr.addr.addr6))
|
||||
{
|
||||
char *s = daemon->dhcp_buff2;
|
||||
int lease_type = LEASE_NA;
|
||||
|
||||
if (s[0] == 'T')
|
||||
{
|
||||
lease_type = LEASE_TA;
|
||||
s++;
|
||||
}
|
||||
|
||||
if ((lease = lease6_allocate(&addr.addr.addr6, lease_type)))
|
||||
{
|
||||
lease_set_iaid(lease, strtoul(s, NULL, 10));
|
||||
domain = get_domain6(&lease->addr6);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else
|
||||
return 0;
|
||||
|
||||
if (!lease)
|
||||
die (_("too many stored leases"), NULL, EC_MISC);
|
||||
|
||||
if (strcmp(daemon->packet, "*") != 0)
|
||||
clid_len = parse_hex(daemon->packet, (unsigned char *)daemon->packet, 255, NULL, NULL);
|
||||
|
||||
lease_set_hwaddr(lease, (unsigned char *)daemon->dhcp_buff2, (unsigned char *)daemon->packet,
|
||||
hw_len, hw_type, clid_len, now, 0);
|
||||
|
||||
if (strcmp(daemon->dhcp_buff, "*") != 0)
|
||||
lease_set_hostname(lease, daemon->dhcp_buff, 0, domain, NULL);
|
||||
|
||||
ei = atol(daemon->dhcp_buff3);
|
||||
|
||||
#ifdef HAVE_BROKEN_RTC
|
||||
if (ei != 0)
|
||||
lease->expires = (time_t)ei + now;
|
||||
else
|
||||
lease->expires = (time_t)0;
|
||||
lease->length = ei;
|
||||
#else
|
||||
/* strictly time_t is opaque, but this hack should work on all sane systems,
|
||||
even when sizeof(time_t) == 8 */
|
||||
lease->expires = (time_t)ei;
|
||||
#endif
|
||||
|
||||
/* set these correctly: the "old" events are generated later from
|
||||
the startup synthesised SIGHUP. */
|
||||
lease->flags &= ~(LEASE_NEW | LEASE_CHANGED);
|
||||
|
||||
*daemon->dhcp_buff3 = *daemon->dhcp_buff2 = '\0';
|
||||
}
|
||||
|
||||
return (items == 0 || items == EOF);
|
||||
}
|
||||
|
||||
void lease_init(time_t now)
|
||||
{
|
||||
FILE *leasestream;
|
||||
|
||||
|
||||
leases_left = daemon->dhcp_max;
|
||||
|
||||
|
||||
if (option_bool(OPT_LEASE_RO))
|
||||
{
|
||||
/* run "<lease_change_script> init" once to get the
|
||||
initial state of the database. If leasefile-ro is
|
||||
set without a script, we just do without any
|
||||
set without a script, we just do without any
|
||||
lease database. */
|
||||
#ifdef HAVE_SCRIPT
|
||||
if (daemon->lease_change_command)
|
||||
@@ -56,99 +161,24 @@ void lease_init(time_t now)
|
||||
{
|
||||
/* NOTE: need a+ mode to create file if it doesn't exist */
|
||||
leasestream = daemon->lease_stream = fopen(daemon->lease_file, "a+");
|
||||
|
||||
|
||||
if (!leasestream)
|
||||
die(_("cannot open or create lease file %s: %s"), daemon->lease_file, EC_FILE);
|
||||
|
||||
|
||||
/* a+ mode leaves pointer at end. */
|
||||
rewind(leasestream);
|
||||
}
|
||||
|
||||
/* client-id max length is 255 which is 255*2 digits + 254 colons
|
||||
borrow DNS packet buffer which is always larger than 1000 bytes */
|
||||
|
||||
if (leasestream)
|
||||
while (fscanf(leasestream, "%255s %255s", daemon->dhcp_buff3, daemon->dhcp_buff2) == 2)
|
||||
{
|
||||
#ifdef HAVE_DHCP6
|
||||
if (strcmp(daemon->dhcp_buff3, "duid") == 0)
|
||||
{
|
||||
daemon->duid_len = parse_hex(daemon->dhcp_buff2, (unsigned char *)daemon->dhcp_buff2, 130, NULL, NULL);
|
||||
daemon->duid = safe_malloc(daemon->duid_len);
|
||||
memcpy(daemon->duid, daemon->dhcp_buff2, daemon->duid_len);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
{
|
||||
if (!read_leases(now, leasestream))
|
||||
my_syslog(MS_DHCP | LOG_ERR, _("failed to parse lease database, invalid line: %s %s %s %s ..."),
|
||||
daemon->dhcp_buff3, daemon->dhcp_buff2,
|
||||
daemon->namebuff, daemon->dhcp_buff);
|
||||
|
||||
ei = atol(daemon->dhcp_buff3);
|
||||
|
||||
if (fscanf(leasestream, " %64s %255s %764s",
|
||||
daemon->namebuff, daemon->dhcp_buff, daemon->packet) != 3)
|
||||
break;
|
||||
|
||||
clid_len = 0;
|
||||
if (strcmp(daemon->packet, "*") != 0)
|
||||
clid_len = parse_hex(daemon->packet, (unsigned char *)daemon->packet, 255, NULL, NULL);
|
||||
|
||||
if (inet_pton(AF_INET, daemon->namebuff, &addr.addr.addr4) &&
|
||||
(lease = lease4_allocate(addr.addr.addr4)))
|
||||
{
|
||||
hw_len = parse_hex(daemon->dhcp_buff2, (unsigned char *)daemon->dhcp_buff2, DHCP_CHADDR_MAX, NULL, &hw_type);
|
||||
/* For backwards compatibility, no explict MAC address type means ether. */
|
||||
if (hw_type == 0 && hw_len != 0)
|
||||
hw_type = ARPHRD_ETHER;
|
||||
|
||||
lease_set_hwaddr(lease, (unsigned char *)daemon->dhcp_buff2, (unsigned char *)daemon->packet,
|
||||
hw_len, hw_type, clid_len, now, 0);
|
||||
|
||||
if (strcmp(daemon->dhcp_buff, "*") != 0)
|
||||
lease_set_hostname(lease, daemon->dhcp_buff, 0, get_domain(lease->addr), NULL);
|
||||
}
|
||||
#ifdef HAVE_DHCP6
|
||||
else if (inet_pton(AF_INET6, daemon->namebuff, &addr.addr.addr6))
|
||||
{
|
||||
char *s = daemon->dhcp_buff2;
|
||||
int lease_type = LEASE_NA;
|
||||
int iaid;
|
||||
|
||||
if (s[0] == 'T')
|
||||
{
|
||||
lease_type = LEASE_TA;
|
||||
s++;
|
||||
}
|
||||
|
||||
iaid = strtoul(s, NULL, 10);
|
||||
|
||||
if ((lease = lease6_allocate(&addr.addr.addr6, lease_type)))
|
||||
{
|
||||
lease_set_hwaddr(lease, NULL, (unsigned char *)daemon->packet, 0, 0, clid_len, now, 0);
|
||||
lease_set_iaid(lease, iaid);
|
||||
if (strcmp(daemon->dhcp_buff, "*") != 0)
|
||||
lease_set_hostname(lease, daemon->dhcp_buff, 0, get_domain6((struct in6_addr *)lease->hwaddr), NULL);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else
|
||||
break;
|
||||
|
||||
if (!lease)
|
||||
die (_("too many stored leases"), NULL, EC_MISC);
|
||||
|
||||
#ifdef HAVE_BROKEN_RTC
|
||||
if (ei != 0)
|
||||
lease->expires = (time_t)ei + now;
|
||||
else
|
||||
lease->expires = (time_t)0;
|
||||
lease->length = ei;
|
||||
#else
|
||||
/* strictly time_t is opaque, but this hack should work on all sane systems,
|
||||
even when sizeof(time_t) == 8 */
|
||||
lease->expires = (time_t)ei;
|
||||
#endif
|
||||
|
||||
/* set these correctly: the "old" events are generated later from
|
||||
the startup synthesised SIGHUP. */
|
||||
lease->flags &= ~(LEASE_NEW | LEASE_CHANGED);
|
||||
}
|
||||
if (ferror(leasestream))
|
||||
die(_("failed to read lease file %s: %s"), daemon->lease_file, EC_FILE);
|
||||
}
|
||||
|
||||
#ifdef HAVE_SCRIPT
|
||||
if (!daemon->lease_stream)
|
||||
@@ -162,6 +192,7 @@ void lease_init(time_t now)
|
||||
errno = ENOENT;
|
||||
else if (WEXITSTATUS(rc) == 126)
|
||||
errno = EACCES;
|
||||
|
||||
die(_("cannot run lease-init script %s: %s"), daemon->lease_change_command, EC_FILE);
|
||||
}
|
||||
|
||||
@@ -198,7 +229,7 @@ void lease_update_from_configs(void)
|
||||
else if ((name = host_from_dns(lease->addr)))
|
||||
lease_set_hostname(lease, name, 1, get_domain(lease->addr), NULL); /* updates auth flag only */
|
||||
}
|
||||
|
||||
|
||||
static void ourprintf(int *errp, char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
@@ -352,16 +383,21 @@ static int find_interface_v4(struct in_addr local, int if_index, char *label,
|
||||
struct in_addr netmask, struct in_addr broadcast, void *vparam)
|
||||
{
|
||||
struct dhcp_lease *lease;
|
||||
|
||||
int prefix = netmask_length(netmask);
|
||||
|
||||
(void) label;
|
||||
(void) broadcast;
|
||||
(void) vparam;
|
||||
|
||||
for (lease = leases; lease; lease = lease->next)
|
||||
if (!(lease->flags & (LEASE_TA | LEASE_NA)))
|
||||
if (is_same_net(local, lease->addr, netmask))
|
||||
lease_set_interface(lease, if_index, *((time_t *)vparam));
|
||||
|
||||
if (!(lease->flags & (LEASE_TA | LEASE_NA)) &&
|
||||
is_same_net(local, lease->addr, netmask) &&
|
||||
prefix > lease->new_prefixlen)
|
||||
{
|
||||
lease->new_interface = if_index;
|
||||
lease->new_prefixlen = prefix;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -371,17 +407,23 @@ static int find_interface_v6(struct in6_addr *local, int prefix,
|
||||
int preferred, int valid, void *vparam)
|
||||
{
|
||||
struct dhcp_lease *lease;
|
||||
|
||||
|
||||
(void)scope;
|
||||
(void)flags;
|
||||
(void)preferred;
|
||||
(void)valid;
|
||||
(void)vparam;
|
||||
|
||||
for (lease = leases; lease; lease = lease->next)
|
||||
if ((lease->flags & (LEASE_TA | LEASE_NA)))
|
||||
if (is_same_net6(local, &lease->addr6, prefix))
|
||||
lease_set_interface(lease, if_index, *((time_t *)vparam));
|
||||
|
||||
if (is_same_net6(local, &lease->addr6, prefix) && prefix > lease->new_prefixlen) {
|
||||
/* save prefix length for comparison, as we might get shorter matching
|
||||
* prefix in upcoming netlink GETADDR responses
|
||||
* */
|
||||
lease->new_interface = if_index;
|
||||
lease->new_prefixlen = prefix;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -395,7 +437,7 @@ void lease_ping_reply(struct in6_addr *sender, unsigned char *packet, char *inte
|
||||
|
||||
void lease_update_slaac(time_t now)
|
||||
{
|
||||
/* Called when we contruct a new RA-names context, to add putative
|
||||
/* Called when we construct a new RA-names context, to add putative
|
||||
new SLAAC addresses to existing leases. */
|
||||
|
||||
struct dhcp_lease *lease;
|
||||
@@ -414,10 +456,19 @@ void lease_update_slaac(time_t now)
|
||||
start-time. */
|
||||
void lease_find_interfaces(time_t now)
|
||||
{
|
||||
struct dhcp_lease *lease;
|
||||
|
||||
for (lease = leases; lease; lease = lease->next)
|
||||
lease->new_prefixlen = lease->new_interface = 0;
|
||||
|
||||
iface_enumerate(AF_INET, &now, find_interface_v4);
|
||||
#ifdef HAVE_DHCP6
|
||||
iface_enumerate(AF_INET6, &now, find_interface_v6);
|
||||
#endif
|
||||
|
||||
for (lease = leases; lease; lease = lease->next)
|
||||
if (lease->new_interface != 0)
|
||||
lease_set_interface(lease, lease->new_interface, now);
|
||||
}
|
||||
|
||||
#ifdef HAVE_DHCP6
|
||||
@@ -756,7 +807,7 @@ void lease_set_expires(struct dhcp_lease *lease, unsigned int len, time_t now)
|
||||
{
|
||||
exp = now + (time_t)len;
|
||||
/* Check for 2038 overflow. Make the lease
|
||||
inifinite in that case, as the least disruptive
|
||||
infinite in that case, as the least disruptive
|
||||
thing we can do. */
|
||||
if (difftime(exp, now) <= 0.0)
|
||||
exp = 0;
|
||||
@@ -793,9 +844,9 @@ void lease_set_iaid(struct dhcp_lease *lease, int iaid)
|
||||
}
|
||||
#endif
|
||||
|
||||
void lease_set_hwaddr(struct dhcp_lease *lease, unsigned char *hwaddr,
|
||||
unsigned char *clid, int hw_len, int hw_type, int clid_len,
|
||||
time_t now, int force)
|
||||
void lease_set_hwaddr(struct dhcp_lease *lease, const unsigned char *hwaddr,
|
||||
const unsigned char *clid, int hw_len, int hw_type,
|
||||
int clid_len, time_t now, int force)
|
||||
{
|
||||
#ifdef HAVE_DHCP6
|
||||
int change = force;
|
||||
@@ -877,7 +928,7 @@ static void kill_name(struct dhcp_lease *lease)
|
||||
lease->hostname = lease->fqdn = NULL;
|
||||
}
|
||||
|
||||
void lease_set_hostname(struct dhcp_lease *lease, char *name, int auth, char *domain, char *config_domain)
|
||||
void lease_set_hostname(struct dhcp_lease *lease, const char *name, int auth, char *domain, char *config_domain)
|
||||
{
|
||||
struct dhcp_lease *lease_tmp;
|
||||
char *new_name = NULL, *new_fqdn = NULL;
|
||||
@@ -1090,18 +1141,22 @@ int do_script_run(time_t now)
|
||||
}
|
||||
|
||||
#ifdef HAVE_SCRIPT
|
||||
/* delim == -1 -> delim = 0, but embedded 0s, creating extra records, are OK. */
|
||||
void lease_add_extradata(struct dhcp_lease *lease, unsigned char *data, unsigned int len, int delim)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
/* check for embeded NULLs */
|
||||
for (i = 0; i < len; i++)
|
||||
if (data[i] == 0)
|
||||
{
|
||||
len = i;
|
||||
break;
|
||||
}
|
||||
|
||||
if (delim == -1)
|
||||
delim = 0;
|
||||
else
|
||||
/* check for embedded NULLs */
|
||||
for (i = 0; i < len; i++)
|
||||
if (data[i] == 0)
|
||||
{
|
||||
len = i;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((lease->extradata_size - lease->extradata_len) < (len + 1))
|
||||
{
|
||||
size_t newsz = lease->extradata_len + len + 100;
|
||||
|
||||
21
src/log.c
21
src/log.c
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2014 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2018 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
|
||||
@@ -154,7 +154,7 @@ static void log_write(void)
|
||||
|
||||
while (entries)
|
||||
{
|
||||
/* The data in the payoad is written with a terminating zero character
|
||||
/* The data in the payload is written with a terminating zero character
|
||||
and the length reflects this. For a stream connection we need to
|
||||
send the zero as a record terminator, but this isn't done for a
|
||||
datagram connection, so treat the length as one less than reality
|
||||
@@ -288,7 +288,9 @@ void my_syslog(int priority, const char *format, ...)
|
||||
func = "-tftp";
|
||||
else if ((LOG_FACMASK & priority) == MS_DHCP)
|
||||
func = "-dhcp";
|
||||
|
||||
else if ((LOG_FACMASK & priority) == MS_SCRIPT)
|
||||
func = "-script";
|
||||
|
||||
#ifdef LOG_PRI
|
||||
priority = LOG_PRI(priority);
|
||||
#else
|
||||
@@ -421,25 +423,22 @@ void my_syslog(int priority, const char *format, ...)
|
||||
}
|
||||
}
|
||||
|
||||
void set_log_writer(fd_set *set, int *maxfdp)
|
||||
void set_log_writer(void)
|
||||
{
|
||||
if (entries && log_fd != -1 && connection_good)
|
||||
{
|
||||
FD_SET(log_fd, set);
|
||||
bump_maxfd(log_fd, maxfdp);
|
||||
}
|
||||
poll_listen(log_fd, POLLOUT);
|
||||
}
|
||||
|
||||
void check_log_writer(fd_set *set)
|
||||
void check_log_writer(int force)
|
||||
{
|
||||
if (log_fd != -1 && (!set || FD_ISSET(log_fd, set)))
|
||||
if (log_fd != -1 && (force || poll_check(log_fd, POLLOUT)))
|
||||
log_write();
|
||||
}
|
||||
|
||||
void flush_log(void)
|
||||
{
|
||||
/* write until queue empty, but don't loop forever if there's
|
||||
no connection to the syslog in existance */
|
||||
no connection to the syslog in existence */
|
||||
while (log_fd != -1)
|
||||
{
|
||||
struct timespec waiter;
|
||||
|
||||
117
src/loop.c
Normal file
117
src/loop.c
Normal file
@@ -0,0 +1,117 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2018 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_LOOP
|
||||
static ssize_t loop_make_probe(u32 uid);
|
||||
|
||||
void loop_send_probes()
|
||||
{
|
||||
struct server *serv;
|
||||
|
||||
if (!option_bool(OPT_LOOP_DETECT))
|
||||
return;
|
||||
|
||||
/* Loop through all upstream servers not for particular domains, and send a query to that server which is
|
||||
identifiable, via the uid. If we see that query back again, then the server is looping, and we should not use it. */
|
||||
for (serv = daemon->servers; serv; serv = serv->next)
|
||||
if (!(serv->flags &
|
||||
(SERV_LITERAL_ADDRESS | SERV_NO_ADDR | SERV_USE_RESOLV | SERV_NO_REBIND | SERV_HAS_DOMAIN | SERV_FOR_NODOTS | SERV_LOOP)))
|
||||
{
|
||||
ssize_t len = loop_make_probe(serv->uid);
|
||||
int fd;
|
||||
struct randfd *rfd = NULL;
|
||||
|
||||
if (serv->sfd)
|
||||
fd = serv->sfd->fd;
|
||||
else
|
||||
{
|
||||
if (!(rfd = allocate_rfd(serv->addr.sa.sa_family)))
|
||||
continue;
|
||||
fd = rfd->fd;
|
||||
}
|
||||
|
||||
while (retry_send(sendto(fd, daemon->packet, len, 0,
|
||||
&serv->addr.sa, sa_len(&serv->addr))));
|
||||
|
||||
free_rfd(rfd);
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t loop_make_probe(u32 uid)
|
||||
{
|
||||
struct dns_header *header = (struct dns_header *)daemon->packet;
|
||||
unsigned char *p = (unsigned char *)(header+1);
|
||||
|
||||
/* packet buffer overwritten */
|
||||
daemon->srv_save = NULL;
|
||||
|
||||
header->id = rand16();
|
||||
header->ancount = header->nscount = header->arcount = htons(0);
|
||||
header->qdcount = htons(1);
|
||||
header->hb3 = HB3_RD;
|
||||
header->hb4 = 0;
|
||||
SET_OPCODE(header, QUERY);
|
||||
|
||||
*p++ = 8;
|
||||
sprintf((char *)p, "%.8x", uid);
|
||||
p += 8;
|
||||
*p++ = strlen(LOOP_TEST_DOMAIN);
|
||||
strcpy((char *)p, LOOP_TEST_DOMAIN); /* Add terminating zero */
|
||||
p += strlen(LOOP_TEST_DOMAIN) + 1;
|
||||
|
||||
PUTSHORT(LOOP_TEST_TYPE, p);
|
||||
PUTSHORT(C_IN, p);
|
||||
|
||||
return p - (unsigned char *)header;
|
||||
}
|
||||
|
||||
|
||||
int detect_loop(char *query, int type)
|
||||
{
|
||||
int i;
|
||||
u32 uid;
|
||||
struct server *serv;
|
||||
|
||||
if (!option_bool(OPT_LOOP_DETECT))
|
||||
return 0;
|
||||
|
||||
if (type != LOOP_TEST_TYPE ||
|
||||
strlen(LOOP_TEST_DOMAIN) + 9 != strlen(query) ||
|
||||
strstr(query, LOOP_TEST_DOMAIN) != query + 9)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
if (!isxdigit(query[i]))
|
||||
return 0;
|
||||
|
||||
uid = strtol(query, NULL, 16);
|
||||
|
||||
for (serv = daemon->servers; serv; serv = serv->next)
|
||||
if (!(serv->flags &
|
||||
(SERV_LITERAL_ADDRESS | SERV_NO_ADDR | SERV_USE_RESOLV | SERV_NO_REBIND | SERV_HAS_DOMAIN | SERV_FOR_NODOTS | SERV_LOOP)) &&
|
||||
uid == serv->uid)
|
||||
{
|
||||
serv->flags |= SERV_LOOP;
|
||||
check_servers(); /* log new state */
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2014 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2018 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
|
||||
@@ -38,7 +38,7 @@
|
||||
static struct iovec iov;
|
||||
static u32 netlink_pid;
|
||||
|
||||
static int nl_async(struct nlmsghdr *h);
|
||||
static void nl_async(struct nlmsghdr *h);
|
||||
|
||||
void netlink_init(void)
|
||||
{
|
||||
@@ -73,7 +73,7 @@ void netlink_init(void)
|
||||
}
|
||||
|
||||
if (daemon->netlinkfd == -1 ||
|
||||
getsockname(daemon->netlinkfd, (struct sockaddr *)&addr, &slen) == 1)
|
||||
getsockname(daemon->netlinkfd, (struct sockaddr *)&addr, &slen) == -1)
|
||||
die(_("cannot create netlink socket: %s"), NULL, EC_MISC);
|
||||
|
||||
/* save pid assigned by bind() and retrieved by getsockname() */
|
||||
@@ -142,7 +142,7 @@ int iface_enumerate(int family, void *parm, int (*callback)())
|
||||
struct nlmsghdr *h;
|
||||
ssize_t len;
|
||||
static unsigned int seq = 0;
|
||||
int callback_ok = 1, newaddr = 0;
|
||||
int callback_ok = 1;
|
||||
|
||||
struct {
|
||||
struct nlmsghdr nlh;
|
||||
@@ -169,10 +169,10 @@ int iface_enumerate(int family, void *parm, int (*callback)())
|
||||
req.g.rtgen_family = family;
|
||||
|
||||
/* Don't block in recvfrom if send fails */
|
||||
while((len = sendto(daemon->netlinkfd, (void *)&req, sizeof(req), 0,
|
||||
(struct sockaddr *)&addr, sizeof(addr))) == -1 && retry_send());
|
||||
|
||||
if (len == -1)
|
||||
while(retry_send(sendto(daemon->netlinkfd, (void *)&req, sizeof(req), 0,
|
||||
(struct sockaddr *)&addr, sizeof(addr))));
|
||||
|
||||
if (errno != 0)
|
||||
return 0;
|
||||
|
||||
while (1)
|
||||
@@ -188,24 +188,19 @@ int iface_enumerate(int family, void *parm, int (*callback)())
|
||||
}
|
||||
|
||||
for (h = (struct nlmsghdr *)iov.iov_base; NLMSG_OK(h, (size_t)len); h = NLMSG_NEXT(h, len))
|
||||
if (h->nlmsg_seq != seq || h->nlmsg_pid != netlink_pid || h->nlmsg_type == NLMSG_ERROR)
|
||||
if (h->nlmsg_pid != netlink_pid || h->nlmsg_type == NLMSG_ERROR)
|
||||
{
|
||||
/* May be multicast arriving async */
|
||||
if (nl_async(h))
|
||||
{
|
||||
newaddr = 1;
|
||||
enumerate_interfaces(1); /* reset */
|
||||
}
|
||||
nl_async(h);
|
||||
}
|
||||
else if (h->nlmsg_seq != seq)
|
||||
{
|
||||
/* May be part of incomplete response to previous request after
|
||||
ENOBUFS. Drop it. */
|
||||
continue;
|
||||
}
|
||||
else if (h->nlmsg_type == NLMSG_DONE)
|
||||
{
|
||||
/* handle async new interface address arrivals, these have to be done
|
||||
after we complete as we're not re-entrant */
|
||||
if (newaddr)
|
||||
newaddress(dnsmasq_time());
|
||||
|
||||
return callback_ok;
|
||||
}
|
||||
return callback_ok;
|
||||
else if (h->nlmsg_type == RTM_NEWADDR && family != AF_UNSPEC && family != AF_LOCAL)
|
||||
{
|
||||
struct ifaddrmsg *ifa = NLMSG_DATA(h);
|
||||
@@ -219,7 +214,8 @@ int iface_enumerate(int family, void *parm, int (*callback)())
|
||||
struct in_addr netmask, addr, broadcast;
|
||||
char *label = NULL;
|
||||
|
||||
netmask.s_addr = htonl(0xffffffff << (32 - ifa->ifa_prefixlen));
|
||||
netmask.s_addr = htonl(~(in_addr_t)0 << (32 - ifa->ifa_prefixlen));
|
||||
|
||||
addr.s_addr = 0;
|
||||
broadcast.s_addr = 0;
|
||||
|
||||
@@ -298,7 +294,8 @@ int iface_enumerate(int family, void *parm, int (*callback)())
|
||||
rta = RTA_NEXT(rta, len1);
|
||||
}
|
||||
|
||||
if (inaddr && mac && callback_ok)
|
||||
if (!(neigh->ndm_state & (NUD_NOARP | NUD_INCOMPLETE | NUD_FAILED)) &&
|
||||
inaddr && mac && callback_ok)
|
||||
if (!((*callback)(neigh->ndm_family, inaddr, mac, maclen, parm)))
|
||||
callback_ok = 0;
|
||||
}
|
||||
@@ -330,11 +327,11 @@ int iface_enumerate(int family, void *parm, int (*callback)())
|
||||
}
|
||||
}
|
||||
|
||||
void netlink_multicast(time_t now)
|
||||
void netlink_multicast(void)
|
||||
{
|
||||
ssize_t len;
|
||||
struct nlmsghdr *h;
|
||||
int flags, newaddr = 0;
|
||||
int flags;
|
||||
|
||||
/* don't risk blocking reading netlink messages here. */
|
||||
if ((flags = fcntl(daemon->netlinkfd, F_GETFL)) == -1 ||
|
||||
@@ -343,24 +340,19 @@ void netlink_multicast(time_t now)
|
||||
|
||||
if ((len = netlink_recv()) != -1)
|
||||
for (h = (struct nlmsghdr *)iov.iov_base; NLMSG_OK(h, (size_t)len); h = NLMSG_NEXT(h, len))
|
||||
if (nl_async(h))
|
||||
newaddr = 1;
|
||||
nl_async(h);
|
||||
|
||||
/* restore non-blocking status */
|
||||
fcntl(daemon->netlinkfd, F_SETFL, flags);
|
||||
|
||||
if (newaddr)
|
||||
newaddress(now);
|
||||
}
|
||||
|
||||
static int nl_async(struct nlmsghdr *h)
|
||||
static void nl_async(struct nlmsghdr *h)
|
||||
{
|
||||
if (h->nlmsg_type == NLMSG_ERROR)
|
||||
{
|
||||
struct nlmsgerr *err = NLMSG_DATA(h);
|
||||
if (err->error != 0)
|
||||
my_syslog(LOG_ERR, _("netlink returns error: %s"), strerror(-(err->error)));
|
||||
return 0;
|
||||
}
|
||||
else if (h->nlmsg_pid == 0 && h->nlmsg_type == RTM_NEWROUTE)
|
||||
{
|
||||
@@ -372,31 +364,10 @@ static int nl_async(struct nlmsghdr *h)
|
||||
struct rtmsg *rtm = NLMSG_DATA(h);
|
||||
|
||||
if (rtm->rtm_type == RTN_UNICAST && rtm->rtm_scope == RT_SCOPE_LINK)
|
||||
{
|
||||
/* Force re-reading resolv file right now, for luck. */
|
||||
daemon->last_resolv = 0;
|
||||
|
||||
if (daemon->srv_save)
|
||||
{
|
||||
int fd;
|
||||
|
||||
if (daemon->srv_save->sfd)
|
||||
fd = daemon->srv_save->sfd->fd;
|
||||
else if (daemon->rfd_save && daemon->rfd_save->refcount != 0)
|
||||
fd = daemon->rfd_save->fd;
|
||||
else
|
||||
return 0;
|
||||
|
||||
while(sendto(fd, daemon->packet, daemon->packet_len, 0,
|
||||
&daemon->srv_save->addr.sa, sa_len(&daemon->srv_save->addr)) == -1 && retry_send());
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
queue_event(EVENT_NEWROUTE);
|
||||
}
|
||||
else if (h->nlmsg_type == RTM_NEWADDR || h->nlmsg_type == RTM_DELADDR)
|
||||
return 1; /* clever bind mode - rescan */
|
||||
|
||||
return 0;
|
||||
queue_event(EVENT_NEWADDR);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
530
src/network.c
530
src/network.c
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2014 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2018 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
|
||||
@@ -16,10 +16,6 @@
|
||||
|
||||
#include "dnsmasq.h"
|
||||
|
||||
#ifndef IN6_IS_ADDR_ULA
|
||||
#define IN6_IS_ADDR_ULA(a) ((((__const uint32_t *) (a))[0] & htonl (0xfe00000)) == htonl (0xfc000000))
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LINUX_NETWORK
|
||||
|
||||
int indextoname(int fd, int index, char *name)
|
||||
@@ -182,7 +178,7 @@ int iface_check(int family, struct all_addr *addr, char *name, int *auth)
|
||||
}
|
||||
|
||||
|
||||
/* Fix for problem that the kernel sometimes reports the loopback inerface as the
|
||||
/* Fix for problem that the kernel sometimes reports the loopback interface as the
|
||||
arrival interface when a packet originates locally, even when sent to address of
|
||||
an interface other than the loopback. Accept packet if it arrived via a loopback
|
||||
interface, even when we're not accepting packets that way, as long as the destination
|
||||
@@ -240,7 +236,7 @@ struct iface_param {
|
||||
};
|
||||
|
||||
static int iface_allowed(struct iface_param *param, int if_index, char *label,
|
||||
union mysockaddr *addr, struct in_addr netmask, int prefixlen, int dad)
|
||||
union mysockaddr *addr, struct in_addr netmask, int prefixlen, int iface_flags)
|
||||
{
|
||||
struct irec *iface;
|
||||
int mtu = 0, loopback;
|
||||
@@ -248,6 +244,7 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label,
|
||||
int tftp_ok = !!option_bool(OPT_TFTP);
|
||||
int dhcp_ok = 1;
|
||||
int auth_dns = 0;
|
||||
int is_label = 0;
|
||||
#if defined(HAVE_DHCP) || defined(HAVE_TFTP)
|
||||
struct iname *tmp;
|
||||
#endif
|
||||
@@ -268,7 +265,42 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label,
|
||||
|
||||
if (!label)
|
||||
label = ifr.ifr_name;
|
||||
else
|
||||
is_label = strcmp(label, ifr.ifr_name);
|
||||
|
||||
/* maintain a list of all addresses on all interfaces for --local-service option */
|
||||
if (option_bool(OPT_LOCAL_SERVICE))
|
||||
{
|
||||
struct addrlist *al;
|
||||
|
||||
if (param->spare)
|
||||
{
|
||||
al = param->spare;
|
||||
param->spare = al->next;
|
||||
}
|
||||
else
|
||||
al = whine_malloc(sizeof(struct addrlist));
|
||||
|
||||
if (al)
|
||||
{
|
||||
al->next = daemon->interface_addrs;
|
||||
daemon->interface_addrs = al;
|
||||
al->prefixlen = prefixlen;
|
||||
|
||||
if (addr->sa.sa_family == AF_INET)
|
||||
{
|
||||
al->addr.addr.addr4 = addr->in.sin_addr;
|
||||
al->flags = 0;
|
||||
}
|
||||
#ifdef HAVE_IPV6
|
||||
else
|
||||
{
|
||||
al->addr.addr.addr6 = addr->in6.sin6_addr;
|
||||
al->flags = ADDRLIST_IPV6;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_IPV6
|
||||
if (addr->sa.sa_family != AF_INET6 || !IN6_IS_ADDR_LINKLOCAL(&addr->in6.sin6_addr))
|
||||
@@ -359,6 +391,10 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label,
|
||||
{
|
||||
al->addr.addr.addr6 = addr->in6.sin6_addr;
|
||||
al->flags = ADDRLIST_IPV6;
|
||||
/* Privacy addresses and addresses still undergoing DAD and deprecated addresses
|
||||
don't appear in forward queries, but will in reverse ones. */
|
||||
if (!(iface_flags & IFACE_PERMANENT) || (iface_flags & (IFACE_DEPRECATED | IFACE_TENTATIVE)))
|
||||
al->flags |= ADDRLIST_REVONLY;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -370,7 +406,7 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label,
|
||||
for (iface = daemon->interfaces; iface; iface = iface->next)
|
||||
if (sockaddr_isequal(&iface->addr, addr))
|
||||
{
|
||||
iface->dad = dad;
|
||||
iface->dad = !!(iface_flags & IFACE_TENTATIVE);
|
||||
iface->found = 1; /* for garbage collection */
|
||||
return 1;
|
||||
}
|
||||
@@ -445,10 +481,11 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label,
|
||||
iface->dhcp_ok = dhcp_ok;
|
||||
iface->dns_auth = auth_dns;
|
||||
iface->mtu = mtu;
|
||||
iface->dad = dad;
|
||||
iface->dad = !!(iface_flags & IFACE_TENTATIVE);
|
||||
iface->found = 1;
|
||||
iface->done = iface->multicast_done = iface->warned = 0;
|
||||
iface->index = if_index;
|
||||
iface->label = is_label;
|
||||
if ((iface->name = whine_malloc(strlen(ifr.ifr_name)+1)))
|
||||
{
|
||||
strcpy(iface->name, ifr.ifr_name);
|
||||
@@ -490,7 +527,7 @@ static int iface_allowed_v6(struct in6_addr *local, int prefix,
|
||||
else
|
||||
addr.in6.sin6_scope_id = 0;
|
||||
|
||||
return iface_allowed((struct iface_param *)vparam, if_index, NULL, &addr, netmask, prefix, !!(flags & IFACE_TENTATIVE));
|
||||
return iface_allowed((struct iface_param *)vparam, if_index, NULL, &addr, netmask, prefix, flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -499,13 +536,14 @@ static int iface_allowed_v4(struct in_addr local, int if_index, char *label,
|
||||
{
|
||||
union mysockaddr addr;
|
||||
int prefix, bit;
|
||||
|
||||
(void)broadcast; /* warning */
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
#ifdef HAVE_SOCKADDR_SA_LEN
|
||||
addr.in.sin_len = sizeof(addr.in);
|
||||
#endif
|
||||
addr.in.sin_family = AF_INET;
|
||||
addr.in.sin_addr = broadcast; /* warning */
|
||||
addr.in.sin_addr = local;
|
||||
addr.in.sin_port = htons(daemon->port);
|
||||
|
||||
@@ -518,7 +556,7 @@ static int iface_allowed_v4(struct in_addr local, int if_index, char *label,
|
||||
int enumerate_interfaces(int reset)
|
||||
{
|
||||
static struct addrlist *spare = NULL;
|
||||
static int done = 0, active = 0;
|
||||
static int done = 0;
|
||||
struct iface_param param;
|
||||
int errsave, ret = 1;
|
||||
struct addrlist *addr, *tmp;
|
||||
@@ -537,14 +575,11 @@ int enumerate_interfaces(int reset)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (done || active)
|
||||
if (done)
|
||||
return 1;
|
||||
|
||||
done = 1;
|
||||
|
||||
/* protect against recusive calls from iface_enumerate(); */
|
||||
active = 1;
|
||||
|
||||
if ((param.fd = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
|
||||
return 0;
|
||||
|
||||
@@ -565,6 +600,15 @@ int enumerate_interfaces(int reset)
|
||||
intname->addr = NULL;
|
||||
}
|
||||
|
||||
/* Remove list of addresses of local interfaces */
|
||||
for (addr = daemon->interface_addrs; addr; addr = tmp)
|
||||
{
|
||||
tmp = addr->next;
|
||||
addr->next = spare;
|
||||
spare = addr;
|
||||
}
|
||||
daemon->interface_addrs = NULL;
|
||||
|
||||
#ifdef HAVE_AUTH
|
||||
/* remove addresses stored against auth_zone subnets, but not
|
||||
ones configured as address literals */
|
||||
@@ -604,7 +648,7 @@ int enumerate_interfaces(int reset)
|
||||
/* Garbage-collect listeners listening on addresses that no longer exist.
|
||||
Does nothing when not binding interfaces or for listeners on localhost,
|
||||
since the ->iface field is NULL. Note that this needs the protections
|
||||
against re-entrancy, hence it's here. It also means there's a possibility,
|
||||
against reentrancy, hence it's here. It also means there's a possibility,
|
||||
in OPT_CLEVERBIND mode, that at listener will just disappear after
|
||||
a call to enumerate_interfaces, this is checked OK on all calls. */
|
||||
struct listener *l, *tmp, **up;
|
||||
@@ -635,10 +679,8 @@ int enumerate_interfaces(int reset)
|
||||
}
|
||||
|
||||
errno = errsave;
|
||||
|
||||
spare = param.spare;
|
||||
active = 0;
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -661,7 +703,7 @@ static int make_sock(union mysockaddr *addr, int type, int dienow)
|
||||
|
||||
if ((fd = socket(family, type, 0)) == -1)
|
||||
{
|
||||
int port, errsav;
|
||||
int port, errsave;
|
||||
char *s;
|
||||
|
||||
/* No error if the kernel just doesn't support this IP flavour */
|
||||
@@ -671,7 +713,7 @@ static int make_sock(union mysockaddr *addr, int type, int dienow)
|
||||
return -1;
|
||||
|
||||
err:
|
||||
errsav = errno;
|
||||
errsave = errno;
|
||||
port = prettyprint_addr(addr, daemon->addrbuff);
|
||||
if (!option_bool(OPT_NOWILD) && !option_bool(OPT_CLEVERBIND))
|
||||
sprintf(daemon->addrbuff, "port %d", port);
|
||||
@@ -680,7 +722,7 @@ static int make_sock(union mysockaddr *addr, int type, int dienow)
|
||||
if (fd != -1)
|
||||
close (fd);
|
||||
|
||||
errno = errsav;
|
||||
errno = errsave;
|
||||
|
||||
if (dienow)
|
||||
{
|
||||
@@ -708,7 +750,7 @@ static int make_sock(union mysockaddr *addr, int type, int dienow)
|
||||
|
||||
if (type == SOCK_STREAM)
|
||||
{
|
||||
if (listen(fd, 5) == -1)
|
||||
if (listen(fd, TCP_BACKLOG) == -1)
|
||||
goto err;
|
||||
}
|
||||
else if (family == AF_INET)
|
||||
@@ -772,10 +814,11 @@ int tcp_interface(int fd, int af)
|
||||
int opt = 1;
|
||||
struct cmsghdr *cmptr;
|
||||
struct msghdr msg;
|
||||
socklen_t len;
|
||||
|
||||
/* use mshdr do that the CMSDG_* macros are available */
|
||||
/* use mshdr so that the CMSDG_* macros are available */
|
||||
msg.msg_control = daemon->packet;
|
||||
msg.msg_controllen = daemon->packet_buff_sz;
|
||||
msg.msg_controllen = len = daemon->packet_buff_sz;
|
||||
|
||||
/* we overwrote the buffer... */
|
||||
daemon->srv_save = NULL;
|
||||
@@ -783,18 +826,21 @@ int tcp_interface(int fd, int af)
|
||||
if (af == AF_INET)
|
||||
{
|
||||
if (setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &opt, sizeof(opt)) != -1 &&
|
||||
getsockopt(fd, IPPROTO_IP, IP_PKTOPTIONS, msg.msg_control, (socklen_t *)&msg.msg_controllen) != -1)
|
||||
for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
|
||||
if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_PKTINFO)
|
||||
{
|
||||
union {
|
||||
unsigned char *c;
|
||||
struct in_pktinfo *p;
|
||||
} p;
|
||||
|
||||
p.c = CMSG_DATA(cmptr);
|
||||
if_index = p.p->ipi_ifindex;
|
||||
}
|
||||
getsockopt(fd, IPPROTO_IP, IP_PKTOPTIONS, msg.msg_control, &len) != -1)
|
||||
{
|
||||
msg.msg_controllen = len;
|
||||
for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
|
||||
if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_PKTINFO)
|
||||
{
|
||||
union {
|
||||
unsigned char *c;
|
||||
struct in_pktinfo *p;
|
||||
} p;
|
||||
|
||||
p.c = CMSG_DATA(cmptr);
|
||||
if_index = p.p->ipi_ifindex;
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef HAVE_IPV6
|
||||
else
|
||||
@@ -812,9 +858,10 @@ int tcp_interface(int fd, int af)
|
||||
#endif
|
||||
|
||||
if (set_ipv6pktinfo(fd) &&
|
||||
getsockopt(fd, IPPROTO_IPV6, PKTOPTIONS, msg.msg_control, (socklen_t *)&msg.msg_controllen) != -1)
|
||||
getsockopt(fd, IPPROTO_IPV6, PKTOPTIONS, msg.msg_control, &len) != -1)
|
||||
{
|
||||
for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
|
||||
msg.msg_controllen = len;
|
||||
for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
|
||||
if (cmptr->cmsg_level == IPPROTO_IPV6 && cmptr->cmsg_type == daemon->v6pktinfo)
|
||||
{
|
||||
union {
|
||||
@@ -991,6 +1038,15 @@ void warn_bound_listeners(void)
|
||||
my_syslog(LOG_WARNING, _("LOUD WARNING: use --bind-dynamic rather than --bind-interfaces to avoid DNS amplification attacks via these interface(s)"));
|
||||
}
|
||||
|
||||
void warn_wild_labels(void)
|
||||
{
|
||||
struct irec *iface;
|
||||
|
||||
for (iface = daemon->interfaces; iface; iface = iface->next)
|
||||
if (iface->found && iface->name && iface->label)
|
||||
my_syslog(LOG_WARNING, _("warning: using interface %s instead"), iface->name);
|
||||
}
|
||||
|
||||
void warn_int_names(void)
|
||||
{
|
||||
struct interface_name *intname;
|
||||
@@ -1039,23 +1095,30 @@ void join_multicast(int dienow)
|
||||
|
||||
if ((daemon->doing_dhcp6 || daemon->relay6) &&
|
||||
setsockopt(daemon->dhcp6fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq)) == -1)
|
||||
err = 1;
|
||||
err = errno;
|
||||
|
||||
inet_pton(AF_INET6, ALL_SERVERS, &mreq.ipv6mr_multiaddr);
|
||||
|
||||
if (daemon->doing_dhcp6 &&
|
||||
setsockopt(daemon->dhcp6fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq)) == -1)
|
||||
err = 1;
|
||||
err = errno;
|
||||
|
||||
inet_pton(AF_INET6, ALL_ROUTERS, &mreq.ipv6mr_multiaddr);
|
||||
|
||||
if (daemon->doing_ra &&
|
||||
setsockopt(daemon->icmp6fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq)) == -1)
|
||||
err = 1;
|
||||
err = errno;
|
||||
|
||||
if (err)
|
||||
{
|
||||
char *s = _("interface %s failed to join DHCPv6 multicast group: %s");
|
||||
errno = err;
|
||||
|
||||
#ifdef HAVE_LINUX_NETWORK
|
||||
if (errno == ENOMEM)
|
||||
my_syslog(LOG_ERR, _("try increasing /proc/sys/net/core/optmem_max"));
|
||||
#endif
|
||||
|
||||
if (dienow)
|
||||
die(s, iface->name, EC_BADNET);
|
||||
else
|
||||
@@ -1075,7 +1138,7 @@ int random_sock(int family)
|
||||
if ((fd = socket(family, SOCK_DGRAM, 0)) != -1)
|
||||
{
|
||||
union mysockaddr addr;
|
||||
unsigned int ports_avail = 65536u - (unsigned short)daemon->min_port;
|
||||
unsigned int ports_avail = ((unsigned short)daemon->max_port - (unsigned short)daemon->min_port) + 1;
|
||||
int tries = ports_avail < 30 ? 3 * ports_avail : 100;
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
@@ -1086,10 +1149,7 @@ int random_sock(int family)
|
||||
if (fix_fd(fd))
|
||||
while(tries--)
|
||||
{
|
||||
unsigned short port = rand16();
|
||||
|
||||
if (daemon->min_port != 0)
|
||||
port = htons(daemon->min_port + (port % ((unsigned short)ports_avail)));
|
||||
unsigned short port = htons(daemon->min_port + (rand16() % ((unsigned short)ports_avail)));
|
||||
|
||||
if (family == AF_INET)
|
||||
{
|
||||
@@ -1124,7 +1184,7 @@ int random_sock(int family)
|
||||
}
|
||||
|
||||
|
||||
int local_bind(int fd, union mysockaddr *addr, char *intname, int is_tcp)
|
||||
int local_bind(int fd, union mysockaddr *addr, char *intname, unsigned int ifindex, int is_tcp)
|
||||
{
|
||||
union mysockaddr addr_copy = *addr;
|
||||
|
||||
@@ -1141,7 +1201,25 @@ int local_bind(int fd, union mysockaddr *addr, char *intname, int is_tcp)
|
||||
|
||||
if (bind(fd, (struct sockaddr *)&addr_copy, sa_len(&addr_copy)) == -1)
|
||||
return 0;
|
||||
|
||||
|
||||
if (!is_tcp && ifindex > 0)
|
||||
{
|
||||
#if defined(IP_UNICAST_IF)
|
||||
if (addr_copy.sa.sa_family == AF_INET)
|
||||
{
|
||||
uint32_t ifindex_opt = htonl(ifindex);
|
||||
return setsockopt(fd, IPPROTO_IP, IP_UNICAST_IF, &ifindex_opt, sizeof(ifindex_opt)) == 0;
|
||||
}
|
||||
#endif
|
||||
#if defined(HAVE_IPV6) && defined (IPV6_UNICAST_IF)
|
||||
if (addr_copy.sa.sa_family == AF_INET6)
|
||||
{
|
||||
uint32_t ifindex_opt = htonl(ifindex);
|
||||
return setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_IF, &ifindex_opt, sizeof(ifindex_opt)) == 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(SO_BINDTODEVICE)
|
||||
if (intname[0] != 0 &&
|
||||
setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, intname, IF_NAMESIZE) == -1)
|
||||
@@ -1154,8 +1232,10 @@ int local_bind(int fd, union mysockaddr *addr, char *intname, int is_tcp)
|
||||
static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname)
|
||||
{
|
||||
struct serverfd *sfd;
|
||||
unsigned int ifindex = 0;
|
||||
int errsave;
|
||||
|
||||
int opt = 1;
|
||||
|
||||
/* when using random ports, servers which would otherwise use
|
||||
the INADDR_ANY/port0 socket have sfd set to NULL */
|
||||
if (!daemon->osport && intname[0] == 0)
|
||||
@@ -1174,11 +1254,15 @@ static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname)
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (intname && strlen(intname) != 0)
|
||||
ifindex = if_nametoindex(intname); /* index == 0 when not binding to an interface */
|
||||
|
||||
/* may have a suitable one already */
|
||||
for (sfd = daemon->sfds; sfd; sfd = sfd->next )
|
||||
if (sockaddr_isequal(&sfd->source_addr, addr) &&
|
||||
strcmp(intname, sfd->interface) == 0)
|
||||
strcmp(intname, sfd->interface) == 0 &&
|
||||
ifindex == sfd->ifindex)
|
||||
return sfd;
|
||||
|
||||
/* need to make a new one. */
|
||||
@@ -1191,20 +1275,24 @@ static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname)
|
||||
free(sfd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!local_bind(sfd->fd, addr, intname, 0) || !fix_fd(sfd->fd))
|
||||
|
||||
if ((addr->sa.sa_family == AF_INET6 && setsockopt(sfd->fd, IPPROTO_IPV6, IPV6_V6ONLY, &opt, sizeof(opt)) == -1) ||
|
||||
!local_bind(sfd->fd, addr, intname, ifindex, 0) || !fix_fd(sfd->fd))
|
||||
{
|
||||
errsave = errno; /* save error from bind. */
|
||||
errsave = errno; /* save error from bind/setsockopt. */
|
||||
close(sfd->fd);
|
||||
free(sfd);
|
||||
errno = errsave;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
strcpy(sfd->interface, intname);
|
||||
sfd->source_addr = *addr;
|
||||
sfd->next = daemon->sfds;
|
||||
sfd->ifindex = ifindex;
|
||||
sfd->preallocated = 0;
|
||||
daemon->sfds = sfd;
|
||||
|
||||
return sfd;
|
||||
}
|
||||
|
||||
@@ -1213,6 +1301,7 @@ static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname)
|
||||
void pre_allocate_sfds(void)
|
||||
{
|
||||
struct server *srv;
|
||||
struct serverfd *sfd;
|
||||
|
||||
if (daemon->query_port != 0)
|
||||
{
|
||||
@@ -1224,7 +1313,8 @@ void pre_allocate_sfds(void)
|
||||
#ifdef HAVE_SOCKADDR_SA_LEN
|
||||
addr.in.sin_len = sizeof(struct sockaddr_in);
|
||||
#endif
|
||||
allocate_sfd(&addr, "");
|
||||
if ((sfd = allocate_sfd(&addr, "")))
|
||||
sfd->preallocated = 1;
|
||||
#ifdef HAVE_IPV6
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.in6.sin6_family = AF_INET6;
|
||||
@@ -1233,7 +1323,8 @@ void pre_allocate_sfds(void)
|
||||
#ifdef HAVE_SOCKADDR_SA_LEN
|
||||
addr.in6.sin6_len = sizeof(struct sockaddr_in6);
|
||||
#endif
|
||||
allocate_sfd(&addr, "");
|
||||
if ((sfd = allocate_sfd(&addr, "")))
|
||||
sfd->preallocated = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1254,87 +1345,275 @@ void pre_allocate_sfds(void)
|
||||
}
|
||||
}
|
||||
|
||||
void mark_servers(int flag)
|
||||
{
|
||||
struct server *serv;
|
||||
|
||||
/* mark everything with argument flag */
|
||||
for (serv = daemon->servers; serv; serv = serv->next)
|
||||
{
|
||||
if (serv->flags & flag)
|
||||
serv->flags |= SERV_MARK;
|
||||
#ifdef HAVE_LOOP
|
||||
/* Give looped servers another chance */
|
||||
serv->flags &= ~SERV_LOOP;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void cleanup_servers(void)
|
||||
{
|
||||
struct server *serv, *tmp, **up;
|
||||
|
||||
/* unlink and free anything still marked. */
|
||||
for (serv = daemon->servers, up = &daemon->servers; serv; serv = tmp)
|
||||
{
|
||||
tmp = serv->next;
|
||||
if (serv->flags & SERV_MARK)
|
||||
{
|
||||
server_gone(serv);
|
||||
*up = serv->next;
|
||||
if (serv->domain)
|
||||
free(serv->domain);
|
||||
free(serv);
|
||||
}
|
||||
else
|
||||
up = &serv->next;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LOOP
|
||||
/* Now we have a new set of servers, test for loops. */
|
||||
loop_send_probes();
|
||||
#endif
|
||||
}
|
||||
|
||||
void add_update_server(int flags,
|
||||
union mysockaddr *addr,
|
||||
union mysockaddr *source_addr,
|
||||
const char *interface,
|
||||
const char *domain)
|
||||
{
|
||||
struct server *serv, *next = NULL;
|
||||
char *domain_str = NULL;
|
||||
|
||||
/* See if there is a suitable candidate, and unmark */
|
||||
for (serv = daemon->servers; serv; serv = serv->next)
|
||||
if (serv->flags & SERV_MARK)
|
||||
{
|
||||
if (domain)
|
||||
{
|
||||
if (!(serv->flags & SERV_HAS_DOMAIN) || !hostname_isequal(domain, serv->domain))
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (serv->flags & SERV_HAS_DOMAIN)
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (serv)
|
||||
{
|
||||
domain_str = serv->domain;
|
||||
next = serv->next;
|
||||
}
|
||||
else if ((serv = whine_malloc(sizeof (struct server))))
|
||||
{
|
||||
/* Not found, create a new one. */
|
||||
if (domain && !(domain_str = whine_malloc(strlen(domain)+1)))
|
||||
{
|
||||
free(serv);
|
||||
serv = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct server *s;
|
||||
/* Add to the end of the chain, for order */
|
||||
if (!daemon->servers)
|
||||
daemon->servers = serv;
|
||||
else
|
||||
{
|
||||
for (s = daemon->servers; s->next; s = s->next);
|
||||
s->next = serv;
|
||||
}
|
||||
if (domain)
|
||||
strcpy(domain_str, domain);
|
||||
}
|
||||
}
|
||||
|
||||
if (serv)
|
||||
{
|
||||
memset(serv, 0, sizeof(struct server));
|
||||
serv->flags = flags;
|
||||
serv->domain = domain_str;
|
||||
serv->next = next;
|
||||
serv->queries = serv->failed_queries = 0;
|
||||
#ifdef HAVE_LOOP
|
||||
serv->uid = rand32();
|
||||
#endif
|
||||
|
||||
if (domain)
|
||||
serv->flags |= SERV_HAS_DOMAIN;
|
||||
|
||||
if (interface)
|
||||
strcpy(serv->interface, interface);
|
||||
if (addr)
|
||||
serv->addr = *addr;
|
||||
if (source_addr)
|
||||
serv->source_addr = *source_addr;
|
||||
}
|
||||
}
|
||||
|
||||
void check_servers(void)
|
||||
{
|
||||
struct irec *iface;
|
||||
struct server *new, *tmp, *ret = NULL;
|
||||
int port = 0;
|
||||
struct server *serv;
|
||||
struct serverfd *sfd, *tmp, **up;
|
||||
int port = 0, count;
|
||||
int locals = 0;
|
||||
|
||||
/* interface may be new since startup */
|
||||
if (!option_bool(OPT_NOWILD))
|
||||
enumerate_interfaces(0);
|
||||
|
||||
for (new = daemon->servers; new; new = tmp)
|
||||
{
|
||||
tmp = new->next;
|
||||
|
||||
if (!(new->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR | SERV_USE_RESOLV | SERV_NO_REBIND)))
|
||||
{
|
||||
port = prettyprint_addr(&new->addr, daemon->namebuff);
|
||||
|
||||
/* don't garbage collect pre-allocated sfds. */
|
||||
for (sfd = daemon->sfds; sfd; sfd = sfd->next)
|
||||
sfd->used = sfd->preallocated;
|
||||
|
||||
for (count = 0, serv = daemon->servers; serv; serv = serv->next)
|
||||
{
|
||||
if (!(serv->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR | SERV_USE_RESOLV | SERV_NO_REBIND)))
|
||||
{
|
||||
/* Init edns_pktsz for newly created server records. */
|
||||
if (serv->edns_pktsz == 0)
|
||||
serv->edns_pktsz = daemon->edns_pktsz;
|
||||
|
||||
#ifdef HAVE_DNSSEC
|
||||
if (option_bool(OPT_DNSSEC_VALID))
|
||||
{
|
||||
if (!(serv->flags & SERV_FOR_NODOTS))
|
||||
serv->flags |= SERV_DO_DNSSEC;
|
||||
|
||||
/* Disable DNSSEC validation when using server=/domain/.... servers
|
||||
unless there's a configured trust anchor. */
|
||||
if (serv->flags & SERV_HAS_DOMAIN)
|
||||
{
|
||||
struct ds_config *ds;
|
||||
char *domain = serv->domain;
|
||||
|
||||
/* .example.com is valid */
|
||||
while (*domain == '.')
|
||||
domain++;
|
||||
|
||||
for (ds = daemon->ds; ds; ds = ds->next)
|
||||
if (ds->name[0] != 0 && hostname_isequal(domain, ds->name))
|
||||
break;
|
||||
|
||||
if (!ds)
|
||||
serv->flags &= ~SERV_DO_DNSSEC;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
port = prettyprint_addr(&serv->addr, daemon->namebuff);
|
||||
|
||||
/* 0.0.0.0 is nothing, the stack treats it like 127.0.0.1 */
|
||||
if (new->addr.sa.sa_family == AF_INET &&
|
||||
new->addr.in.sin_addr.s_addr == 0)
|
||||
if (serv->addr.sa.sa_family == AF_INET &&
|
||||
serv->addr.in.sin_addr.s_addr == 0)
|
||||
{
|
||||
free(new);
|
||||
serv->flags |= SERV_MARK;
|
||||
continue;
|
||||
}
|
||||
|
||||
for (iface = daemon->interfaces; iface; iface = iface->next)
|
||||
if (sockaddr_isequal(&new->addr, &iface->addr))
|
||||
if (sockaddr_isequal(&serv->addr, &iface->addr))
|
||||
break;
|
||||
if (iface)
|
||||
{
|
||||
my_syslog(LOG_WARNING, _("ignoring nameserver %s - local interface"), daemon->namebuff);
|
||||
free(new);
|
||||
serv->flags |= SERV_MARK;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Do we need a socket set? */
|
||||
if (!new->sfd &&
|
||||
!(new->sfd = allocate_sfd(&new->source_addr, new->interface)) &&
|
||||
if (!serv->sfd &&
|
||||
!(serv->sfd = allocate_sfd(&serv->source_addr, serv->interface)) &&
|
||||
errno != 0)
|
||||
{
|
||||
my_syslog(LOG_WARNING,
|
||||
_("ignoring nameserver %s - cannot make/bind socket: %s"),
|
||||
daemon->namebuff, strerror(errno));
|
||||
free(new);
|
||||
serv->flags |= SERV_MARK;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (serv->sfd)
|
||||
serv->sfd->used = 1;
|
||||
}
|
||||
|
||||
/* reverse order - gets it right. */
|
||||
new->next = ret;
|
||||
ret = new;
|
||||
|
||||
if (!(new->flags & SERV_NO_REBIND))
|
||||
if (!(serv->flags & SERV_NO_REBIND) && !(serv->flags & SERV_LITERAL_ADDRESS))
|
||||
{
|
||||
if (new->flags & (SERV_HAS_DOMAIN | SERV_FOR_NODOTS | SERV_USE_RESOLV))
|
||||
if (++count > SERVERS_LOGGED)
|
||||
continue;
|
||||
|
||||
if (serv->flags & (SERV_HAS_DOMAIN | SERV_FOR_NODOTS | SERV_USE_RESOLV))
|
||||
{
|
||||
char *s1, *s2;
|
||||
if (!(new->flags & SERV_HAS_DOMAIN))
|
||||
char *s1, *s2, *s3 = "";
|
||||
#ifdef HAVE_DNSSEC
|
||||
if (option_bool(OPT_DNSSEC_VALID) && !(serv->flags & SERV_DO_DNSSEC))
|
||||
s3 = _("(no DNSSEC)");
|
||||
#endif
|
||||
if (!(serv->flags & SERV_HAS_DOMAIN))
|
||||
s1 = _("unqualified"), s2 = _("names");
|
||||
else if (strlen(new->domain) == 0)
|
||||
else if (strlen(serv->domain) == 0)
|
||||
s1 = _("default"), s2 = "";
|
||||
else
|
||||
s1 = _("domain"), s2 = new->domain;
|
||||
s1 = _("domain"), s2 = serv->domain;
|
||||
|
||||
if (new->flags & SERV_NO_ADDR)
|
||||
my_syslog(LOG_INFO, _("using local addresses only for %s %s"), s1, s2);
|
||||
else if (new->flags & SERV_USE_RESOLV)
|
||||
if (serv->flags & SERV_NO_ADDR)
|
||||
{
|
||||
count--;
|
||||
if (++locals <= LOCALS_LOGGED)
|
||||
my_syslog(LOG_INFO, _("using local addresses only for %s %s"), s1, s2);
|
||||
}
|
||||
else if (serv->flags & SERV_USE_RESOLV)
|
||||
my_syslog(LOG_INFO, _("using standard nameservers for %s %s"), s1, s2);
|
||||
else if (!(new->flags & SERV_LITERAL_ADDRESS))
|
||||
my_syslog(LOG_INFO, _("using nameserver %s#%d for %s %s"), daemon->namebuff, port, s1, s2);
|
||||
else
|
||||
my_syslog(LOG_INFO, _("using nameserver %s#%d for %s %s %s"), daemon->namebuff, port, s1, s2, s3);
|
||||
}
|
||||
else if (new->interface[0] != 0)
|
||||
my_syslog(LOG_INFO, _("using nameserver %s#%d(via %s)"), daemon->namebuff, port, new->interface);
|
||||
#ifdef HAVE_LOOP
|
||||
else if (serv->flags & SERV_LOOP)
|
||||
my_syslog(LOG_INFO, _("NOT using nameserver %s#%d - query loop detected"), daemon->namebuff, port);
|
||||
#endif
|
||||
else if (serv->interface[0] != 0)
|
||||
my_syslog(LOG_INFO, _("using nameserver %s#%d(via %s)"), daemon->namebuff, port, serv->interface);
|
||||
else
|
||||
my_syslog(LOG_INFO, _("using nameserver %s#%d"), daemon->namebuff, port);
|
||||
}
|
||||
}
|
||||
|
||||
daemon->servers = ret;
|
||||
if (locals > LOCALS_LOGGED)
|
||||
my_syslog(LOG_INFO, _("using %d more local addresses"), locals - LOCALS_LOGGED);
|
||||
if (count - 1 > SERVERS_LOGGED)
|
||||
my_syslog(LOG_INFO, _("using %d more nameservers"), count - SERVERS_LOGGED - 1);
|
||||
|
||||
/* Remove unused sfds */
|
||||
for (sfd = daemon->sfds, up = &daemon->sfds; sfd; sfd = tmp)
|
||||
{
|
||||
tmp = sfd->next;
|
||||
if (!sfd->used)
|
||||
{
|
||||
*up = sfd->next;
|
||||
close(sfd->fd);
|
||||
free(sfd);
|
||||
}
|
||||
else
|
||||
up = &sfd->next;
|
||||
}
|
||||
|
||||
cleanup_servers();
|
||||
}
|
||||
|
||||
/* Return zero if no servers found, in that case we keep polling.
|
||||
@@ -1343,9 +1622,6 @@ int reload_servers(char *fname)
|
||||
{
|
||||
FILE *f;
|
||||
char *line;
|
||||
struct server *old_servers = NULL;
|
||||
struct server *new_servers = NULL;
|
||||
struct server *serv;
|
||||
int gotone = 0;
|
||||
|
||||
/* buff happens to be MAXDNAME long... */
|
||||
@@ -1354,28 +1630,9 @@ int reload_servers(char *fname)
|
||||
my_syslog(LOG_ERR, _("failed to read %s: %s"), fname, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* move old servers to free list - we can reuse the memory
|
||||
and not risk malloc if there are the same or fewer new servers.
|
||||
Servers which were specced on the command line go to the new list. */
|
||||
for (serv = daemon->servers; serv;)
|
||||
{
|
||||
struct server *tmp = serv->next;
|
||||
if (serv->flags & SERV_FROM_RESOLV)
|
||||
{
|
||||
serv->next = old_servers;
|
||||
old_servers = serv;
|
||||
/* forward table rules reference servers, so have to blow them away */
|
||||
server_gone(serv);
|
||||
}
|
||||
else
|
||||
{
|
||||
serv->next = new_servers;
|
||||
new_servers = serv;
|
||||
}
|
||||
serv = tmp;
|
||||
}
|
||||
|
||||
|
||||
mark_servers(SERV_FROM_RESOLV);
|
||||
|
||||
while ((line = fgets(daemon->namebuff, MAXDNAME, f)))
|
||||
{
|
||||
union mysockaddr addr, source_addr;
|
||||
@@ -1434,49 +1691,23 @@ int reload_servers(char *fname)
|
||||
continue;
|
||||
#endif
|
||||
|
||||
if (old_servers)
|
||||
{
|
||||
serv = old_servers;
|
||||
old_servers = old_servers->next;
|
||||
}
|
||||
else if (!(serv = whine_malloc(sizeof (struct server))))
|
||||
continue;
|
||||
|
||||
/* this list is reverse ordered:
|
||||
it gets reversed again in check_servers */
|
||||
serv->next = new_servers;
|
||||
new_servers = serv;
|
||||
serv->addr = addr;
|
||||
serv->source_addr = source_addr;
|
||||
serv->domain = NULL;
|
||||
serv->interface[0] = 0;
|
||||
serv->sfd = NULL;
|
||||
serv->flags = SERV_FROM_RESOLV;
|
||||
serv->queries = serv->failed_queries = 0;
|
||||
add_update_server(SERV_FROM_RESOLV, &addr, &source_addr, NULL, NULL);
|
||||
gotone = 1;
|
||||
}
|
||||
|
||||
/* Free any memory not used. */
|
||||
while (old_servers)
|
||||
{
|
||||
struct server *tmp = old_servers->next;
|
||||
free(old_servers);
|
||||
old_servers = tmp;
|
||||
}
|
||||
|
||||
daemon->servers = new_servers;
|
||||
fclose(f);
|
||||
cleanup_servers();
|
||||
|
||||
return gotone;
|
||||
}
|
||||
|
||||
#if defined(HAVE_LINUX_NETWORK) || defined(HAVE_BSD_NETWORK)
|
||||
/* Called when addresses are added or deleted from an interface */
|
||||
void newaddress(time_t now)
|
||||
{
|
||||
(void)now;
|
||||
|
||||
if (option_bool(OPT_CLEVERBIND) || daemon->doing_dhcp6 || daemon->relay6 || daemon->doing_ra)
|
||||
if (option_bool(OPT_CLEVERBIND) || option_bool(OPT_LOCAL_SERVICE) ||
|
||||
daemon->doing_dhcp6 || daemon->relay6 || daemon->doing_ra)
|
||||
enumerate_interfaces(0);
|
||||
|
||||
if (option_bool(OPT_CLEVERBIND))
|
||||
@@ -1494,7 +1725,6 @@ void newaddress(time_t now)
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
1310
src/option.c
1310
src/option.c
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2014 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2018 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
|
||||
@@ -29,9 +29,19 @@ void end_opt6(int container)
|
||||
PUTSHORT(len, p);
|
||||
}
|
||||
|
||||
void reset_counter(void)
|
||||
{
|
||||
/* Clear out buffer when starting from beginning */
|
||||
if (daemon->outpacket.iov_base)
|
||||
memset(daemon->outpacket.iov_base, 0, daemon->outpacket.iov_len);
|
||||
|
||||
save_counter(0);
|
||||
}
|
||||
|
||||
int save_counter(int newval)
|
||||
{
|
||||
int ret = outpacket_counter;
|
||||
|
||||
if (newval != -1)
|
||||
outpacket_counter = newval;
|
||||
|
||||
|
||||
125
src/poll.c
Normal file
125
src/poll.c
Normal file
@@ -0,0 +1,125 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2018 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"
|
||||
|
||||
/* Wrapper for poll(). Allocates and extends array of struct pollfds,
|
||||
keeps them in fd order so that we can set and test conditions on
|
||||
fd using a simple but efficient binary chop. */
|
||||
|
||||
/* poll_reset()
|
||||
poll_listen(fd, event)
|
||||
.
|
||||
.
|
||||
poll_listen(fd, event);
|
||||
|
||||
hits = do_poll(timeout);
|
||||
|
||||
if (poll_check(fd, event)
|
||||
.
|
||||
.
|
||||
|
||||
if (poll_check(fd, event)
|
||||
.
|
||||
.
|
||||
|
||||
event is OR of POLLIN, POLLOUT, POLLERR, etc
|
||||
*/
|
||||
|
||||
static struct pollfd *pollfds = NULL;
|
||||
static nfds_t nfds, arrsize = 0;
|
||||
|
||||
/* Binary search. Returns either the pollfd with fd, or
|
||||
if the fd doesn't match, or return equals nfds, the entry
|
||||
to the left of which a new record should be inserted. */
|
||||
static nfds_t fd_search(int fd)
|
||||
{
|
||||
nfds_t left, right, mid;
|
||||
|
||||
if ((right = nfds) == 0)
|
||||
return 0;
|
||||
|
||||
left = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (right == left + 1)
|
||||
return (pollfds[left].fd >= fd) ? left : right;
|
||||
|
||||
mid = (left + right)/2;
|
||||
|
||||
if (pollfds[mid].fd > fd)
|
||||
right = mid;
|
||||
else
|
||||
left = mid;
|
||||
}
|
||||
}
|
||||
|
||||
void poll_reset(void)
|
||||
{
|
||||
nfds = 0;
|
||||
}
|
||||
|
||||
int do_poll(int timeout)
|
||||
{
|
||||
return poll(pollfds, nfds, timeout);
|
||||
}
|
||||
|
||||
int poll_check(int fd, short event)
|
||||
{
|
||||
nfds_t i = fd_search(fd);
|
||||
|
||||
if (i < nfds && pollfds[i].fd == fd)
|
||||
return pollfds[i].revents & event;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void poll_listen(int fd, short event)
|
||||
{
|
||||
nfds_t i = fd_search(fd);
|
||||
|
||||
if (i < nfds && pollfds[i].fd == fd)
|
||||
pollfds[i].events |= event;
|
||||
else
|
||||
{
|
||||
if (arrsize != nfds)
|
||||
memmove(&pollfds[i+1], &pollfds[i], (nfds - i) * sizeof(struct pollfd));
|
||||
else
|
||||
{
|
||||
/* Array too small, extend. */
|
||||
struct pollfd *new;
|
||||
|
||||
arrsize = (arrsize == 0) ? 64 : arrsize * 2;
|
||||
|
||||
if (!(new = whine_malloc(arrsize * sizeof(struct pollfd))))
|
||||
return;
|
||||
|
||||
if (pollfds)
|
||||
{
|
||||
memcpy(new, pollfds, i * sizeof(struct pollfd));
|
||||
memcpy(&new[i+1], &pollfds[i], (nfds - i) * sizeof(struct pollfd));
|
||||
free(pollfds);
|
||||
}
|
||||
|
||||
pollfds = new;
|
||||
}
|
||||
|
||||
pollfds[i].fd = fd;
|
||||
pollfds[i].events = event;
|
||||
nfds++;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2014 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2018 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
|
||||
@@ -49,6 +49,8 @@ struct prefix_opt {
|
||||
#define ICMP6_OPT_SOURCE_MAC 1
|
||||
#define ICMP6_OPT_PREFIX 3
|
||||
#define ICMP6_OPT_MTU 5
|
||||
#define ICMP6_OPT_ADV_INTERVAL 7
|
||||
#define ICMP6_OPT_RT_INFO 24
|
||||
#define ICMP6_OPT_RDNSS 25
|
||||
#define ICMP6_OPT_DNSSL 31
|
||||
|
||||
|
||||
286
src/radv.c
286
src/radv.c
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2014 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2018 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
|
||||
@@ -28,11 +28,12 @@
|
||||
|
||||
struct ra_param {
|
||||
time_t now;
|
||||
int ind, managed, other, found_context, first;
|
||||
int ind, managed, other, first, adv_router;
|
||||
char *if_name;
|
||||
struct dhcp_netid *tags;
|
||||
struct in6_addr link_local, link_global, ula;
|
||||
unsigned int glob_pref_time, link_pref_time, ula_pref_time, adv_interval;
|
||||
unsigned int glob_pref_time, link_pref_time, ula_pref_time, adv_interval, prio;
|
||||
struct dhcp_context *found_context;
|
||||
};
|
||||
|
||||
struct search_param {
|
||||
@@ -40,7 +41,18 @@ struct search_param {
|
||||
char name[IF_NAMESIZE+1];
|
||||
};
|
||||
|
||||
struct alias_param {
|
||||
int iface;
|
||||
struct dhcp_bridge *bridge;
|
||||
int num_alias_ifs;
|
||||
int max_alias_ifs;
|
||||
int *alias_ifs;
|
||||
};
|
||||
|
||||
static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *dest);
|
||||
static void send_ra_alias(time_t now, int iface, char *iface_name, struct in6_addr *dest,
|
||||
int send_iface);
|
||||
static int send_ra_to_aliases(int index, unsigned int type, char *mac, size_t maclen, void *parm);
|
||||
static int add_prefixes(struct in6_addr *local, int prefix,
|
||||
int scope, int if_index, int flags,
|
||||
unsigned int preferred, unsigned int valid, void *vparam);
|
||||
@@ -70,7 +82,7 @@ void ra_init(time_t now)
|
||||
/* ensure this is around even if we're not doing DHCPv6 */
|
||||
expand_buf(&daemon->outpacket, sizeof(struct dhcp_packet));
|
||||
|
||||
/* See if we're guessing SLAAC addresses, if so we need to recieve ping replies */
|
||||
/* See if we're guessing SLAAC addresses, if so we need to receive ping replies */
|
||||
for (context = daemon->dhcp6; context; context = context->next)
|
||||
if ((context->flags & CONTEXT_RA_NAME))
|
||||
break;
|
||||
@@ -100,10 +112,10 @@ void ra_init(time_t now)
|
||||
daemon->icmp6fd = fd;
|
||||
|
||||
if (daemon->doing_ra)
|
||||
ra_start_unsolicted(now, NULL);
|
||||
ra_start_unsolicited(now, NULL);
|
||||
}
|
||||
|
||||
void ra_start_unsolicted(time_t now, struct dhcp_context *context)
|
||||
void ra_start_unsolicited(time_t now, struct dhcp_context *context)
|
||||
{
|
||||
/* init timers so that we do ra's for some/all soon. some ra_times will end up zeroed
|
||||
if it's not appropriate to advertise those contexts.
|
||||
@@ -181,22 +193,51 @@ void icmp6_packet(time_t now)
|
||||
else if (packet[0] == ND_ROUTER_SOLICIT)
|
||||
{
|
||||
char *mac = "";
|
||||
struct dhcp_bridge *bridge, *alias;
|
||||
|
||||
/* look for link-layer address option for logging */
|
||||
if (sz >= 16 && packet[8] == ICMP6_OPT_SOURCE_MAC && (packet[9] * 8) + 8 <= sz)
|
||||
{
|
||||
if ((packet[9] * 8 - 2) * 3 - 1 >= MAXDNAME) {
|
||||
return;
|
||||
}
|
||||
print_mac(daemon->namebuff, &packet[10], (packet[9] * 8) - 2);
|
||||
mac = daemon->namebuff;
|
||||
}
|
||||
|
||||
if (!option_bool(OPT_QUIET_RA))
|
||||
my_syslog(MS_DHCP | LOG_INFO, "RTR-SOLICIT(%s) %s", interface, mac);
|
||||
/* source address may not be valid in solicit request. */
|
||||
send_ra(now, if_index, interface, !IN6_IS_ADDR_UNSPECIFIED(&from.sin6_addr) ? &from.sin6_addr : NULL);
|
||||
|
||||
/* If the incoming interface is an alias of some other one (as
|
||||
specified by the --bridge-interface option), send an RA using
|
||||
the context of the aliased interface. */
|
||||
for (bridge = daemon->bridges; bridge; bridge = bridge->next)
|
||||
{
|
||||
int bridge_index = if_nametoindex(bridge->iface);
|
||||
if (bridge_index)
|
||||
{
|
||||
for (alias = bridge->alias; alias; alias = alias->next)
|
||||
if (wildcard_matchn(alias->iface, interface, IF_NAMESIZE))
|
||||
{
|
||||
/* Send an RA on if_index with information from
|
||||
bridge_index. */
|
||||
send_ra_alias(now, bridge_index, bridge->iface, NULL, if_index);
|
||||
break;
|
||||
}
|
||||
if (alias)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the incoming interface wasn't an alias, send an RA using
|
||||
the context of the incoming interface. */
|
||||
if (!bridge)
|
||||
/* source address may not be valid in solicit request. */
|
||||
send_ra(now, if_index, interface, !IN6_IS_ADDR_UNSPECIFIED(&from.sin6_addr) ? &from.sin6_addr : NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *dest)
|
||||
static void send_ra_alias(time_t now, int iface, char *iface_name, struct in6_addr *dest, int send_iface)
|
||||
{
|
||||
struct ra_packet *ra;
|
||||
struct ra_param parm;
|
||||
@@ -205,33 +246,37 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de
|
||||
struct dhcp_netid iface_id;
|
||||
struct dhcp_opt *opt_cfg;
|
||||
struct ra_interface *ra_param = find_iface_param(iface_name);
|
||||
int done_dns = 0, old_prefix = 0;
|
||||
int done_dns = 0, old_prefix = 0, mtu = 0;
|
||||
unsigned int min_pref_time;
|
||||
#ifdef HAVE_LINUX_NETWORK
|
||||
FILE *f;
|
||||
#endif
|
||||
|
||||
save_counter(0);
|
||||
ra = expand(sizeof(struct ra_packet));
|
||||
|
||||
ra->type = ND_ROUTER_ADVERT;
|
||||
ra->code = 0;
|
||||
ra->hop_limit = hop_limit;
|
||||
ra->flags = calc_prio(ra_param);
|
||||
ra->lifetime = htons(calc_lifetime(ra_param));
|
||||
ra->reachable_time = 0;
|
||||
ra->retrans_time = 0;
|
||||
|
||||
parm.ind = iface;
|
||||
parm.managed = 0;
|
||||
parm.other = 0;
|
||||
parm.found_context = 0;
|
||||
parm.found_context = NULL;
|
||||
parm.adv_router = 0;
|
||||
parm.if_name = iface_name;
|
||||
parm.first = 1;
|
||||
parm.now = now;
|
||||
parm.glob_pref_time = parm.link_pref_time = parm.ula_pref_time = 0;
|
||||
parm.adv_interval = calc_interval(ra_param);
|
||||
parm.prio = calc_prio(ra_param);
|
||||
|
||||
reset_counter();
|
||||
|
||||
if (!(ra = expand(sizeof(struct ra_packet))))
|
||||
return;
|
||||
|
||||
ra->type = ND_ROUTER_ADVERT;
|
||||
ra->code = 0;
|
||||
ra->hop_limit = hop_limit;
|
||||
ra->flags = parm.prio;
|
||||
ra->lifetime = htons(calc_lifetime(ra_param));
|
||||
ra->reachable_time = 0;
|
||||
ra->retrans_time = 0;
|
||||
|
||||
/* set tag with name == interface */
|
||||
iface_id.net = iface_name;
|
||||
iface_id.next = NULL;
|
||||
@@ -269,8 +314,14 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de
|
||||
unsigned int old = difftime(now, context->address_lost_time);
|
||||
|
||||
if (old > context->saved_valid)
|
||||
{
|
||||
{
|
||||
/* We've advertised this enough, time to go */
|
||||
|
||||
/* If this context held the timeout, and there's another context in use
|
||||
transfer the timeout there. */
|
||||
if (context->ra_time != 0 && parm.found_context && parm.found_context->ra_time == 0)
|
||||
new_timeout(parm.found_context, iface_name, now);
|
||||
|
||||
*up = context->next;
|
||||
free(context);
|
||||
}
|
||||
@@ -286,8 +337,7 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de
|
||||
setaddr6part(&local, addr6part(&local) & ~((context->prefix == 64) ? (u64)-1LL : (1LLU << (128 - context->prefix)) - 1LLU));
|
||||
|
||||
|
||||
if ((context->flags &
|
||||
(CONTEXT_RA_ONLY | CONTEXT_RA_NAME | CONTEXT_RA_STATELESS)))
|
||||
if (context->flags & CONTEXT_RA)
|
||||
{
|
||||
do_slaac = 1;
|
||||
if (context->flags & CONTEXT_DHCP)
|
||||
@@ -312,8 +362,10 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de
|
||||
opt->type = ICMP6_OPT_PREFIX;
|
||||
opt->len = 4;
|
||||
opt->prefix_len = context->prefix;
|
||||
/* autonomous only if we're not doing dhcp, always set "on-link" */
|
||||
opt->flags = do_slaac ? 0xC0 : 0x80;
|
||||
/* autonomous only if we're not doing dhcp, set
|
||||
"on-link" unless "off-link" was specified */
|
||||
opt->flags = (do_slaac ? 0x40 : 0) |
|
||||
((context->flags & CONTEXT_RA_OFF_LINK) ? 0 : 0x80);
|
||||
opt->valid_lifetime = htonl(context->saved_valid - old);
|
||||
opt->preferred_lifetime = htonl(0);
|
||||
opt->reserved = 0;
|
||||
@@ -339,24 +391,45 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de
|
||||
if (!old_prefix && !parm.found_context)
|
||||
return;
|
||||
|
||||
#ifdef HAVE_LINUX_NETWORK
|
||||
/* Note that IPv6 MTU is not necessarilly the same as the IPv4 MTU
|
||||
available from SIOCGIFMTU */
|
||||
sprintf(daemon->namebuff, "/proc/sys/net/ipv6/conf/%s/mtu", iface_name);
|
||||
if ((f = fopen(daemon->namebuff, "r")))
|
||||
/* If we're sending router address instead of prefix in at least on prefix,
|
||||
include the advertisement interval option. */
|
||||
if (parm.adv_router)
|
||||
{
|
||||
if (fgets(daemon->namebuff, MAXDNAME, f))
|
||||
{
|
||||
put_opt6_char(ICMP6_OPT_MTU);
|
||||
put_opt6_char(1);
|
||||
put_opt6_short(0);
|
||||
put_opt6_long(atoi(daemon->namebuff));
|
||||
}
|
||||
fclose(f);
|
||||
put_opt6_char(ICMP6_OPT_ADV_INTERVAL);
|
||||
put_opt6_char(1);
|
||||
put_opt6_short(0);
|
||||
/* interval value is in milliseconds */
|
||||
put_opt6_long(1000 * calc_interval(find_iface_param(iface_name)));
|
||||
}
|
||||
|
||||
/* Set the MTU from ra_param if any, an MTU of 0 mean automatic for linux, */
|
||||
/* an MTU of -1 prevents the option from being sent. */
|
||||
if (ra_param)
|
||||
mtu = ra_param->mtu;
|
||||
#ifdef HAVE_LINUX_NETWORK
|
||||
/* Note that IPv6 MTU is not necessarily the same as the IPv4 MTU
|
||||
available from SIOCGIFMTU */
|
||||
if (mtu == 0)
|
||||
{
|
||||
char *mtu_name = ra_param ? ra_param->mtu_name : NULL;
|
||||
sprintf(daemon->namebuff, "/proc/sys/net/ipv6/conf/%s/mtu", mtu_name ? : iface_name);
|
||||
if ((f = fopen(daemon->namebuff, "r")))
|
||||
{
|
||||
if (fgets(daemon->namebuff, MAXDNAME, f))
|
||||
mtu = atoi(daemon->namebuff);
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (mtu > 0)
|
||||
{
|
||||
put_opt6_char(ICMP6_OPT_MTU);
|
||||
put_opt6_char(1);
|
||||
put_opt6_short(0);
|
||||
put_opt6_long(mtu);
|
||||
}
|
||||
|
||||
iface_enumerate(AF_LOCAL, &iface, add_lla);
|
||||
iface_enumerate(AF_LOCAL, &send_iface, add_lla);
|
||||
|
||||
/* RDNSS, RFC 6106, use relevant DHCP6 options */
|
||||
(void)option_filter(parm.tags, NULL, daemon->dhcp_opts6);
|
||||
@@ -464,14 +537,22 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de
|
||||
else
|
||||
{
|
||||
inet_pton(AF_INET6, ALL_NODES, &addr.sin6_addr);
|
||||
setsockopt(daemon->icmp6fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &iface, sizeof(iface));
|
||||
setsockopt(daemon->icmp6fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &send_iface, sizeof(send_iface));
|
||||
}
|
||||
|
||||
while (sendto(daemon->icmp6fd, daemon->outpacket.iov_base, save_counter(0), 0,
|
||||
(struct sockaddr *)&addr, sizeof(addr)) == -1 && retry_send());
|
||||
while (retry_send(sendto(daemon->icmp6fd, daemon->outpacket.iov_base,
|
||||
save_counter(-1), 0, (struct sockaddr *)&addr,
|
||||
sizeof(addr))));
|
||||
|
||||
}
|
||||
|
||||
static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *dest)
|
||||
{
|
||||
/* Send an RA on the same interface that the RA content is based
|
||||
on. */
|
||||
send_ra_alias(now, iface, iface_name, dest, iface);
|
||||
}
|
||||
|
||||
static int add_prefixes(struct in6_addr *local, int prefix,
|
||||
int scope, int if_index, int flags,
|
||||
unsigned int preferred, unsigned int valid, void *vparam)
|
||||
@@ -500,6 +581,8 @@ static int add_prefixes(struct in6_addr *local, int prefix,
|
||||
int do_slaac = 0;
|
||||
int deprecate = 0;
|
||||
int constructed = 0;
|
||||
int adv_router = 0;
|
||||
int off_link = 0;
|
||||
unsigned int time = 0xffffffff;
|
||||
struct dhcp_context *context;
|
||||
|
||||
@@ -511,8 +594,7 @@ static int add_prefixes(struct in6_addr *local, int prefix,
|
||||
{
|
||||
context->saved_valid = valid;
|
||||
|
||||
if ((context->flags &
|
||||
(CONTEXT_RA_ONLY | CONTEXT_RA_NAME | CONTEXT_RA_STATELESS)))
|
||||
if (context->flags & CONTEXT_RA)
|
||||
{
|
||||
do_slaac = 1;
|
||||
if (context->flags & CONTEXT_DHCP)
|
||||
@@ -530,7 +612,17 @@ static int add_prefixes(struct in6_addr *local, int prefix,
|
||||
param->managed = 1;
|
||||
param->other = 1;
|
||||
}
|
||||
|
||||
|
||||
/* Configured to advertise router address, not prefix. See RFC 3775 7.2
|
||||
In this case we do all addresses associated with a context,
|
||||
hence the real_prefix setting here. */
|
||||
if (context->flags & CONTEXT_RA_ROUTER)
|
||||
{
|
||||
adv_router = 1;
|
||||
param->adv_router = 1;
|
||||
real_prefix = context->prefix;
|
||||
}
|
||||
|
||||
/* find floor time, don't reduce below 3 * RA interval. */
|
||||
if (time > context->lease_time)
|
||||
{
|
||||
@@ -556,17 +648,20 @@ static int add_prefixes(struct in6_addr *local, int prefix,
|
||||
/* subsequent prefixes on the same interface
|
||||
and subsequent instances of this prefix don't need timers.
|
||||
Be careful not to find the same prefix twice with different
|
||||
addresses. */
|
||||
addresses unless we're advertising the actual addresses. */
|
||||
if (!(context->flags & CONTEXT_RA_DONE))
|
||||
{
|
||||
if (!param->first)
|
||||
context->ra_time = 0;
|
||||
context->flags |= CONTEXT_RA_DONE;
|
||||
real_prefix = context->prefix;
|
||||
off_link = (context->flags & CONTEXT_RA_OFF_LINK);
|
||||
}
|
||||
|
||||
param->first = 0;
|
||||
param->found_context = 1;
|
||||
param->first = 0;
|
||||
/* found_context is the _last_ one we found, so if there's
|
||||
more than one, it's not the first. */
|
||||
param->found_context = context;
|
||||
}
|
||||
|
||||
/* configured time is ceiling */
|
||||
@@ -607,13 +702,19 @@ static int add_prefixes(struct in6_addr *local, int prefix,
|
||||
if ((opt = expand(sizeof(struct prefix_opt))))
|
||||
{
|
||||
/* zero net part of address */
|
||||
setaddr6part(local, addr6part(local) & ~((real_prefix == 64) ? (u64)-1LL : (1LLU << (128 - real_prefix)) - 1LLU));
|
||||
if (!adv_router)
|
||||
setaddr6part(local, addr6part(local) & ~((real_prefix == 64) ? (u64)-1LL : (1LLU << (128 - real_prefix)) - 1LLU));
|
||||
|
||||
opt->type = ICMP6_OPT_PREFIX;
|
||||
opt->len = 4;
|
||||
opt->prefix_len = real_prefix;
|
||||
/* autonomous only if we're not doing dhcp, always set "on-link" */
|
||||
opt->flags = do_slaac ? 0xC0 : 0x80;
|
||||
/* autonomous only if we're not doing dhcp, set
|
||||
"on-link" unless "off-link" was specified */
|
||||
opt->flags = (off_link ? 0 : 0x80);
|
||||
if (do_slaac)
|
||||
opt->flags |= 0x40;
|
||||
if (adv_router)
|
||||
opt->flags |= 0x20;
|
||||
opt->valid_lifetime = htonl(valid);
|
||||
opt->preferred_lifetime = htonl(preferred);
|
||||
opt->reserved = 0;
|
||||
@@ -655,6 +756,7 @@ time_t periodic_ra(time_t now)
|
||||
struct search_param param;
|
||||
struct dhcp_context *context;
|
||||
time_t next_event;
|
||||
struct alias_param aparam;
|
||||
|
||||
param.now = now;
|
||||
param.iface = 0;
|
||||
@@ -691,7 +793,7 @@ time_t periodic_ra(time_t now)
|
||||
associated with it, because it's for a subnet we dont
|
||||
have an interface on. Probably we're doing DHCP on
|
||||
a remote subnet via a relay. Zero the timer, since we won't
|
||||
ever be able to send ra's and satistfy it. */
|
||||
ever be able to send ra's and satisfy it. */
|
||||
context->ra_time = 0;
|
||||
|
||||
if (param.iface != 0 &&
|
||||
@@ -702,12 +804,84 @@ time_t periodic_ra(time_t now)
|
||||
if (tmp->name && wildcard_match(tmp->name, param.name))
|
||||
break;
|
||||
if (!tmp)
|
||||
send_ra(now, param.iface, param.name, NULL);
|
||||
{
|
||||
send_ra(now, param.iface, param.name, NULL);
|
||||
|
||||
/* Also send on all interfaces that are aliases of this
|
||||
one. */
|
||||
for (aparam.bridge = daemon->bridges;
|
||||
aparam.bridge;
|
||||
aparam.bridge = aparam.bridge->next)
|
||||
if ((int)if_nametoindex(aparam.bridge->iface) == param.iface)
|
||||
{
|
||||
/* Count the number of alias interfaces for this
|
||||
'bridge', by calling iface_enumerate with
|
||||
send_ra_to_aliases and NULL alias_ifs. */
|
||||
aparam.iface = param.iface;
|
||||
aparam.alias_ifs = NULL;
|
||||
aparam.num_alias_ifs = 0;
|
||||
iface_enumerate(AF_LOCAL, &aparam, send_ra_to_aliases);
|
||||
my_syslog(MS_DHCP | LOG_INFO, "RTR-ADVERT(%s) %s => %d alias(es)",
|
||||
param.name, daemon->addrbuff, aparam.num_alias_ifs);
|
||||
|
||||
/* Allocate memory to store the alias interface
|
||||
indices. */
|
||||
aparam.alias_ifs = (int *)whine_malloc(aparam.num_alias_ifs *
|
||||
sizeof(int));
|
||||
if (aparam.alias_ifs)
|
||||
{
|
||||
/* Use iface_enumerate again to get the alias
|
||||
interface indices, then send on each of
|
||||
those. */
|
||||
aparam.max_alias_ifs = aparam.num_alias_ifs;
|
||||
aparam.num_alias_ifs = 0;
|
||||
iface_enumerate(AF_LOCAL, &aparam, send_ra_to_aliases);
|
||||
for (; aparam.num_alias_ifs; aparam.num_alias_ifs--)
|
||||
{
|
||||
my_syslog(MS_DHCP | LOG_INFO, "RTR-ADVERT(%s) %s => i/f %d",
|
||||
param.name, daemon->addrbuff,
|
||||
aparam.alias_ifs[aparam.num_alias_ifs - 1]);
|
||||
send_ra_alias(now,
|
||||
param.iface,
|
||||
param.name,
|
||||
NULL,
|
||||
aparam.alias_ifs[aparam.num_alias_ifs - 1]);
|
||||
}
|
||||
free(aparam.alias_ifs);
|
||||
}
|
||||
|
||||
/* The source interface can only appear in at most
|
||||
one --bridge-interface. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return next_event;
|
||||
}
|
||||
|
||||
|
||||
static int send_ra_to_aliases(int index, unsigned int type, char *mac, size_t maclen, void *parm)
|
||||
{
|
||||
struct alias_param *aparam = (struct alias_param *)parm;
|
||||
char ifrn_name[IFNAMSIZ];
|
||||
struct dhcp_bridge *alias;
|
||||
|
||||
(void)type;
|
||||
(void)mac;
|
||||
(void)maclen;
|
||||
|
||||
if (if_indextoname(index, ifrn_name))
|
||||
for (alias = aparam->bridge->alias; alias; alias = alias->next)
|
||||
if (wildcard_matchn(alias->iface, ifrn_name, IFNAMSIZ))
|
||||
{
|
||||
if (aparam->alias_ifs && (aparam->num_alias_ifs < aparam->max_alias_ifs))
|
||||
aparam->alias_ifs[aparam->num_alias_ifs] = index;
|
||||
aparam->num_alias_ifs++;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int iface_search(struct in6_addr *local, int prefix,
|
||||
int scope, int if_index, int flags,
|
||||
int preferred, int valid, void *vparam)
|
||||
|
||||
1104
src/rfc1035.c
1104
src/rfc1035.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