mirror of
https://github.com/berlin-open-wireless-lab/DAWN.git
synced 2025-02-12 08:41:51 +00:00
first version
This commit is contained in:
commit
f03f55ff92
28 changed files with 5682 additions and 0 deletions
4
CMakeLists.txt
Executable file
4
CMakeLists.txt
Executable file
|
@ -0,0 +1,4 @@
|
||||||
|
cmake_minimum_required(VERSION 2.6)
|
||||||
|
PROJECT(dawn)
|
||||||
|
|
||||||
|
ADD_SUBDIRECTORY(src)
|
33
INSTALL.md
Normal file
33
INSTALL.md
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
### Compiling DAWN
|
||||||
|
|
||||||
|
Add [bowlfeed](https://github.com/berlin-open-wireless-lab/bowl-feed.git) to feeds.conf
|
||||||
|
|
||||||
|
src-git bowlfeed git@github.com:berlin-open-wireless-lab/bowl-feed.git
|
||||||
|
|
||||||
|
Update Feeds
|
||||||
|
|
||||||
|
./scripts/feeds update -a
|
||||||
|
|
||||||
|
Install DAWN
|
||||||
|
|
||||||
|
./scripts/feeds install dawn
|
||||||
|
|
||||||
|
|
||||||
|
Select dawn under
|
||||||
|
|
||||||
|
make menuconfig
|
||||||
|
|
||||||
|
Compile
|
||||||
|
|
||||||
|
make package/dawn/compile
|
||||||
|
|
||||||
|
### Configure Dawn
|
||||||
|
|
||||||
|
Edit settings under
|
||||||
|
|
||||||
|
/etc/config/dawn
|
||||||
|
|
||||||
|
Restart daemon
|
||||||
|
/etc/init.d/dawn restart
|
340
LICENSE
Normal file
340
LICENSE
Normal file
|
@ -0,0 +1,340 @@
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 2, June 1991
|
||||||
|
|
||||||
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc., <http://fsf.org/>
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
License is intended to guarantee your freedom to share and change free
|
||||||
|
software--to make sure the software is free for all its users. This
|
||||||
|
General Public License applies to most of the Free Software
|
||||||
|
Foundation's software and to any other program whose authors commit to
|
||||||
|
using it. (Some other Free Software Foundation software is covered by
|
||||||
|
the GNU Lesser General Public License instead.) You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
this service if you wish), that you receive source code or can get it
|
||||||
|
if you want it, that you can change the software or use pieces of it
|
||||||
|
in new free programs; and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
anyone to deny you these rights or to ask you to surrender the rights.
|
||||||
|
These restrictions translate to certain responsibilities for you if you
|
||||||
|
distribute copies of the software, or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must give the recipients all the rights that
|
||||||
|
you have. You must make sure that they, too, receive or can get the
|
||||||
|
source code. And you must show them these terms so they know their
|
||||||
|
rights.
|
||||||
|
|
||||||
|
We protect your rights with two steps: (1) copyright the software, and
|
||||||
|
(2) offer you this license which gives you legal permission to copy,
|
||||||
|
distribute and/or modify the software.
|
||||||
|
|
||||||
|
Also, for each author's protection and ours, we want to make certain
|
||||||
|
that everyone understands that there is no warranty for this free
|
||||||
|
software. If the software is modified by someone else and passed on, we
|
||||||
|
want its recipients to know that what they have is not the original, so
|
||||||
|
that any problems introduced by others will not reflect on the original
|
||||||
|
authors' reputations.
|
||||||
|
|
||||||
|
Finally, any free program is threatened constantly by software
|
||||||
|
patents. We wish to avoid the danger that redistributors of a free
|
||||||
|
program will individually obtain patent licenses, in effect making the
|
||||||
|
program proprietary. To prevent this, we have made it clear that any
|
||||||
|
patent must be licensed for everyone's free use or not licensed at all.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License applies to any program or other work which contains
|
||||||
|
a notice placed by the copyright holder saying it may be distributed
|
||||||
|
under the terms of this General Public License. The "Program", below,
|
||||||
|
refers to any such program or work, and a "work based on the Program"
|
||||||
|
means either the Program or any derivative work under copyright law:
|
||||||
|
that is to say, a work containing the Program or a portion of it,
|
||||||
|
either verbatim or with modifications and/or translated into another
|
||||||
|
language. (Hereinafter, translation is included without limitation in
|
||||||
|
the term "modification".) Each licensee is addressed as "you".
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running the Program is not restricted, and the output from the Program
|
||||||
|
is covered only if its contents constitute a work based on the
|
||||||
|
Program (independent of having been made by running the Program).
|
||||||
|
Whether that is true depends on what the Program does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Program's
|
||||||
|
source code as you receive it, in any medium, provided that you
|
||||||
|
conspicuously and appropriately publish on each copy an appropriate
|
||||||
|
copyright notice and disclaimer of warranty; keep intact all the
|
||||||
|
notices that refer to this License and to the absence of any warranty;
|
||||||
|
and give any other recipients of the Program a copy of this License
|
||||||
|
along with the Program.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy, and
|
||||||
|
you may at your option offer warranty protection in exchange for a fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Program or any portion
|
||||||
|
of it, thus forming a work based on the Program, and copy and
|
||||||
|
distribute such modifications or work under the terms of Section 1
|
||||||
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) You must cause the modified files to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
b) You must cause any work that you distribute or publish, that in
|
||||||
|
whole or in part contains or is derived from the Program or any
|
||||||
|
part thereof, to be licensed as a whole at no charge to all third
|
||||||
|
parties under the terms of this License.
|
||||||
|
|
||||||
|
c) If the modified program normally reads commands interactively
|
||||||
|
when run, you must cause it, when started running for such
|
||||||
|
interactive use in the most ordinary way, to print or display an
|
||||||
|
announcement including an appropriate copyright notice and a
|
||||||
|
notice that there is no warranty (or else, saying that you provide
|
||||||
|
a warranty) and that users may redistribute the program under
|
||||||
|
these conditions, and telling the user how to view a copy of this
|
||||||
|
License. (Exception: if the Program itself is interactive but
|
||||||
|
does not normally print such an announcement, your work based on
|
||||||
|
the Program is not required to print an announcement.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Program,
|
||||||
|
and can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based
|
||||||
|
on the Program, the distribution of the whole must be on the terms of
|
||||||
|
this License, whose permissions for other licensees extend to the
|
||||||
|
entire whole, and thus to each and every part regardless of who wrote it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Program.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Program
|
||||||
|
with the Program (or with a work based on the Program) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may copy and distribute the Program (or a work based on it,
|
||||||
|
under Section 2) in object code or executable form under the terms of
|
||||||
|
Sections 1 and 2 above provided that you also do one of the following:
|
||||||
|
|
||||||
|
a) Accompany it with the complete corresponding machine-readable
|
||||||
|
source code, which must be distributed under the terms of Sections
|
||||||
|
1 and 2 above on a medium customarily used for software interchange; or,
|
||||||
|
|
||||||
|
b) Accompany it with a written offer, valid for at least three
|
||||||
|
years, to give any third party, for a charge no more than your
|
||||||
|
cost of physically performing source distribution, a complete
|
||||||
|
machine-readable copy of the corresponding source code, to be
|
||||||
|
distributed under the terms of Sections 1 and 2 above on a medium
|
||||||
|
customarily used for software interchange; or,
|
||||||
|
|
||||||
|
c) Accompany it with the information you received as to the offer
|
||||||
|
to distribute corresponding source code. (This alternative is
|
||||||
|
allowed only for noncommercial distribution and only if you
|
||||||
|
received the program in object code or executable form with such
|
||||||
|
an offer, in accord with Subsection b above.)
|
||||||
|
|
||||||
|
The source code for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For an executable work, complete source
|
||||||
|
code means all the source code for all modules it contains, plus any
|
||||||
|
associated interface definition files, plus the scripts used to
|
||||||
|
control compilation and installation of the executable. However, as a
|
||||||
|
special exception, the source code distributed need not include
|
||||||
|
anything that is normally distributed (in either source or binary
|
||||||
|
form) with the major components (compiler, kernel, and so on) of the
|
||||||
|
operating system on which the executable runs, unless that component
|
||||||
|
itself accompanies the executable.
|
||||||
|
|
||||||
|
If distribution of executable or object code is made by offering
|
||||||
|
access to copy from a designated place, then offering equivalent
|
||||||
|
access to copy the source code from the same place counts as
|
||||||
|
distribution of the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
4. You may not copy, modify, sublicense, or distribute the Program
|
||||||
|
except as expressly provided under this License. Any attempt
|
||||||
|
otherwise to copy, modify, sublicense or distribute the Program is
|
||||||
|
void, and will automatically terminate your rights under this License.
|
||||||
|
However, parties who have received copies, or rights, from you under
|
||||||
|
this License will not have their licenses terminated so long as such
|
||||||
|
parties remain in full compliance.
|
||||||
|
|
||||||
|
5. You are not required to accept this License, since you have not
|
||||||
|
signed it. However, nothing else grants you permission to modify or
|
||||||
|
distribute the Program or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Program (or any work based on the
|
||||||
|
Program), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Program or works based on it.
|
||||||
|
|
||||||
|
6. Each time you redistribute the Program (or any work based on the
|
||||||
|
Program), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute or modify the Program subject to
|
||||||
|
these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
|
You are not responsible for enforcing compliance by third parties to
|
||||||
|
this License.
|
||||||
|
|
||||||
|
7. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Program at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Program by
|
||||||
|
all those who receive copies directly or indirectly through you, then
|
||||||
|
the only way you could satisfy both it and this License would be to
|
||||||
|
refrain entirely from distribution of the Program.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under
|
||||||
|
any particular circumstance, the balance of the section is intended to
|
||||||
|
apply and the section as a whole is intended to apply in other
|
||||||
|
circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system, which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is willing
|
||||||
|
to distribute software through any other system and a licensee cannot
|
||||||
|
impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
8. If the distribution and/or use of the Program is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Program under this License
|
||||||
|
may add an explicit geographical distribution limitation excluding
|
||||||
|
those countries, so that distribution is permitted only in or among
|
||||||
|
countries not thus excluded. In such case, this License incorporates
|
||||||
|
the limitation as if written in the body of this License.
|
||||||
|
|
||||||
|
9. The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Program
|
||||||
|
specifies a version number of this License which applies to it and "any
|
||||||
|
later version", you have the option of following the terms and conditions
|
||||||
|
either of that version or of any later version published by the Free
|
||||||
|
Software Foundation. If the Program does not specify a version number of
|
||||||
|
this License, you may choose any version ever published by the Free Software
|
||||||
|
Foundation.
|
||||||
|
|
||||||
|
10. If you wish to incorporate parts of the Program into other free
|
||||||
|
programs whose distribution conditions are different, write to the author
|
||||||
|
to ask for permission. For software which is copyrighted by the Free
|
||||||
|
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||||
|
make exceptions for this. Our decision will be guided by the two goals
|
||||||
|
of preserving the free status of all derivatives of our free software and
|
||||||
|
of promoting the sharing and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||||
|
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||||
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||||
|
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||||
|
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||||
|
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||||
|
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||||
|
REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||||
|
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||||
|
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||||
|
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||||
|
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||||
|
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
{description}
|
||||||
|
Copyright (C) {year} {fullname}
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program is interactive, make it output a short notice like this
|
||||||
|
when it starts in an interactive mode:
|
||||||
|
|
||||||
|
Gnomovision version 69, Copyright (C) year name of author
|
||||||
|
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
|
parts of the General Public License. Of course, the commands you use may
|
||||||
|
be called something other than `show w' and `show c'; they could even be
|
||||||
|
mouse-clicks or menu items--whatever suits your program.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||||
|
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||||
|
|
||||||
|
{signature of Ty Coon}, 1 April 1989
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
|
This General Public License does not permit incorporating your program into
|
||||||
|
proprietary programs. If your program is a subroutine library, you may
|
||||||
|
consider it more useful to permit linking proprietary applications with the
|
||||||
|
library. If this is what you want to do, use the GNU Lesser General
|
||||||
|
Public License instead of this License.
|
||||||
|
|
119
README.md
Normal file
119
README.md
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
![DAWN PICTURE](https://image.ibb.co/nbmNfJ/dawn_bla.png)
|
||||||
|
|
||||||
|
# DAWN
|
||||||
|
Decentralized WiFi Controller
|
||||||
|
|
||||||
|
## Related
|
||||||
|
|
||||||
|
|Repro |Content |
|
||||||
|
|------------------|--------------------------|
|
||||||
|
|[patches-pending](https://github.com/berlin-open-wireless-lab/patches-pending)|Pending OpenWrt Patches DAWN is depending on|
|
||||||
|
|[bowl-feed](https://github.com/berlin-open-wireless-lab/bowl-feed)|Feed for DAWN|
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
See [installation](INSTALL.md).
|
||||||
|
|
||||||
|
## LuCI App
|
||||||
|
There is an luci app called [luci-app-dawn](https://github.com/berlin-open-wireless-lab/bowl-feed).
|
||||||
|
|
||||||
|
## Setting up Routers
|
||||||
|
|
||||||
|
You can find a good guide to configure your router is [here](https://gist.github.com/braian87b/bba9da3a7ac23c35b7f1eecafecdd47d).
|
||||||
|
I setup the OpenWRT Router as dumb APs.
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
|
||||||
|
|Option |Standard | Meaning |
|
||||||
|
|-------------------|---------|---------|
|
||||||
|
|ht_support | '10' |If AP and station support high throughput.|
|
||||||
|
|vht_support | '100' |If AP and station support very high throughput.|
|
||||||
|
|no_ht_support | '0' |If AP and station not supporting high throughput.|
|
||||||
|
|no_vht_support | '0' |If AP and station not supporting very high throughput.
|
||||||
|
|rssi | '10' |If RSSI is greater equal rssi_val.|
|
||||||
|
|low_rssi | '-500' |If RSSI is less than low_rssi_val.|
|
||||||
|
|freq | '100' |If connection is 5Ghz.|
|
||||||
|
|chan_util | '0' |If channel utilization is lower chan_util_val.|
|
||||||
|
|max_chan_util | '-500' |If channel utilization is greater max_chan_util_val.|
|
||||||
|
|rssi_val | '-60' |Threshold for an good RSSI.|
|
||||||
|
|low_rssi_val | '-80' |Threshold for an bad RSSI.|
|
||||||
|
|chan_util_val | '140' |Threshold for an good channel utilization.|
|
||||||
|
|max_chan_util_val | '170' |Threshold for a bad channel utilization.|
|
||||||
|
|min_probe_count | '2' |Minimum number of probe requests aftrer calculating if AP is best and sending a probe response.|
|
||||||
|
|bandwith_threshold | '6' |Threshold for the receiving bit rate indicating if a client is in an active transmission.|
|
||||||
|
|use_station_count | '1' |Use station count as metric.|
|
||||||
|
|max_station_diff | '1' |Maximal station difference that is allowed.|
|
||||||
|
|eval_probe_req | '1' |Evaluate the incoming probe requests.|
|
||||||
|
|eval_auth_req | '1' |Evaluate the incomning authentication reqeuests.|
|
||||||
|
|eval_assoc_req | '1' |Evaluate the incoming association requests.|
|
||||||
|
|deny_auth_reason | '1' |Status code for denying authentications.|
|
||||||
|
|deny_assoc_reason | '17' |Status code for denying associations.|
|
||||||
|
|use_driver_recog | '1' |Allow drivers to connect after a certain time.|
|
||||||
|
|
||||||
|
|
||||||
|
## ubus interface
|
||||||
|
To get an overview of all connected Clients sorted by the SSID.
|
||||||
|
|
||||||
|
root@OpenWrt:~# ubus call dawn get_network
|
||||||
|
{
|
||||||
|
"Free-Cookies": {
|
||||||
|
"00:27:19:XX:XX:XX": {
|
||||||
|
"78:02:F8:XX:XX:XX": {
|
||||||
|
"freq": 2452,
|
||||||
|
"ht": 1,
|
||||||
|
"vht": 0,
|
||||||
|
"collision_count": 4
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"A4:2B:B0:XX:XX:XX": {
|
||||||
|
"48:27:EA:XX:XX:XX: {
|
||||||
|
"freq": 2412,
|
||||||
|
"ht": 1,
|
||||||
|
"vht": 0,
|
||||||
|
"collision_count": 4
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Free-Cookies_5G": {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
To get the hearing map you can use:
|
||||||
|
|
||||||
|
root@OpenWrt:~# ubus call dawn get_hearing_map
|
||||||
|
{
|
||||||
|
"Free-Cookies": {
|
||||||
|
"0E:5B:DB:XX:XX:XX": {
|
||||||
|
"00:27:19:XX:XX:XX": {
|
||||||
|
"signal": -64,
|
||||||
|
"freq": 2452,
|
||||||
|
"ht_support": true,
|
||||||
|
"vht_support": false,
|
||||||
|
"channel_utilization": 12,
|
||||||
|
"num_sta": 1,
|
||||||
|
"ht": 1,
|
||||||
|
"vht": 0,
|
||||||
|
"score": 10
|
||||||
|
},
|
||||||
|
"A4:2B:B0:XX:XX:XX": {
|
||||||
|
"signal": -70,
|
||||||
|
"freq": 2412,
|
||||||
|
"ht_support": true,
|
||||||
|
"vht_support": false,
|
||||||
|
"channel_utilization": 71,
|
||||||
|
"num_sta": 3,
|
||||||
|
"ht": 1,
|
||||||
|
"vht": 0,
|
||||||
|
"score": 10
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
## OpenWrt in a Nutshell
|
||||||
|
|
||||||
|
![OpenWrtInANuthshell](https://raw.githubusercontent.com/PolynomialDivision/upload_stuff/master/dawn_pictures/openwrt_in_a_nutshell_dawn.png)
|
||||||
|
|
||||||
|
|
54
src/CMakeLists.txt
Executable file
54
src/CMakeLists.txt
Executable file
|
@ -0,0 +1,54 @@
|
||||||
|
cmake_minimum_required(VERSION 2.6)
|
||||||
|
PROJECT(dawn)
|
||||||
|
|
||||||
|
INCLUDE_DIRECTORIES(include)
|
||||||
|
|
||||||
|
ADD_DEFINITIONS(-Os -Wall -Werror --std=gnu99 -Wmissing-declarations -Wno-unknown-warning-option -Wno-format-truncation)
|
||||||
|
|
||||||
|
SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
|
||||||
|
|
||||||
|
SET(SOURCES
|
||||||
|
main.c
|
||||||
|
|
||||||
|
storage/datastorage.c
|
||||||
|
include/datastorage.h
|
||||||
|
|
||||||
|
network/networksocket.c
|
||||||
|
include/networksocket.h
|
||||||
|
|
||||||
|
network/broadcastsocket.c
|
||||||
|
include/broadcastsocket.h
|
||||||
|
|
||||||
|
network/multicastsocket.c
|
||||||
|
include/multicastsocket.h
|
||||||
|
|
||||||
|
utils/ubus.c
|
||||||
|
include/ubus.h
|
||||||
|
|
||||||
|
utils/dawn_uci.c
|
||||||
|
include/dawn_uci.h
|
||||||
|
|
||||||
|
crypto/crypto.c
|
||||||
|
include/crypto.h
|
||||||
|
|
||||||
|
include/utils.h
|
||||||
|
utils/utils.c
|
||||||
|
|
||||||
|
include/tcpsocket.h
|
||||||
|
network/tcpsocket.c
|
||||||
|
|
||||||
|
include/dawn_iwinfo.h
|
||||||
|
utils/dawn_iwinfo.c
|
||||||
|
|
||||||
|
utils/ieee80211_utils.c
|
||||||
|
include/ieee80211_utils.h)
|
||||||
|
|
||||||
|
SET(LIBS
|
||||||
|
ubox ubus json-c blobmsg_json uci gcrypt iwinfo)
|
||||||
|
|
||||||
|
ADD_EXECUTABLE(dawn ${SOURCES})
|
||||||
|
|
||||||
|
TARGET_LINK_LIBRARIES(dawn ${LIBS})
|
||||||
|
|
||||||
|
INSTALL(TARGETS dawn
|
||||||
|
RUNTIME DESTINATION /usr/sbin/)
|
100
src/crypto/crypto.c
Normal file
100
src/crypto/crypto.c
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
// based on:
|
||||||
|
// https://github.com/vedantk/gcrypt-example/blob/master/gcry.cc
|
||||||
|
|
||||||
|
#include "crypto.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <gcrypt.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define GCRY_CIPHER GCRY_CIPHER_AES128 // Pick the cipher here
|
||||||
|
#define GCRY_C_MODE GCRY_CIPHER_MODE_ECB // Pick the cipher mode here
|
||||||
|
|
||||||
|
gcry_error_t gcry_error_handle;
|
||||||
|
gcry_cipher_hd_t gcry_cipher_hd;
|
||||||
|
|
||||||
|
void gcrypt_init() {
|
||||||
|
if (!gcry_check_version(GCRYPT_VERSION)) {
|
||||||
|
fprintf(stderr, "gcrypt: library version mismatch");
|
||||||
|
}
|
||||||
|
gcry_error_t err = 0;
|
||||||
|
err = gcry_control(GCRYCTL_SUSPEND_SECMEM_WARN);
|
||||||
|
err |= gcry_control(GCRYCTL_INIT_SECMEM, 16384, 0);
|
||||||
|
err |= gcry_control(GCRYCTL_RESUME_SECMEM_WARN);
|
||||||
|
err |= gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
|
||||||
|
|
||||||
|
if (err) {
|
||||||
|
fprintf(stderr, "gcrypt: failed initialization");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void gcrypt_set_key_and_iv(const char *key, const char *iv) {
|
||||||
|
size_t keylen = gcry_cipher_get_algo_keylen(GCRY_CIPHER);
|
||||||
|
size_t blklen = gcry_cipher_get_algo_blklen(GCRY_CIPHER);
|
||||||
|
|
||||||
|
gcry_error_handle = gcry_cipher_open(
|
||||||
|
&gcry_cipher_hd, // gcry_cipher_hd_t *
|
||||||
|
GCRY_CIPHER, // int
|
||||||
|
GCRY_C_MODE, // int
|
||||||
|
0);
|
||||||
|
if (gcry_error_handle) {
|
||||||
|
fprintf(stderr, "gcry_cipher_open failed: %s/%s\n",
|
||||||
|
gcry_strsource(gcry_error_handle),
|
||||||
|
gcry_strerror(gcry_error_handle));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gcry_error_handle = gcry_cipher_setkey(gcry_cipher_hd, key, keylen);
|
||||||
|
if (gcry_error_handle) {
|
||||||
|
fprintf(stderr, "gcry_cipher_setkey failed: %s/%s\n",
|
||||||
|
gcry_strsource(gcry_error_handle),
|
||||||
|
gcry_strerror(gcry_error_handle));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gcry_error_handle = gcry_cipher_setiv(gcry_cipher_hd, iv, blklen);
|
||||||
|
if (gcry_error_handle) {
|
||||||
|
fprintf(stderr, "gcry_cipher_setiv failed: %s/%s\n",
|
||||||
|
gcry_strsource(gcry_error_handle),
|
||||||
|
gcry_strerror(gcry_error_handle));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// free out buffer after using!
|
||||||
|
char *gcrypt_encrypt_msg(char *msg, size_t msg_length, int *out_length) {
|
||||||
|
if (0U != (msg_length & 0xfU))
|
||||||
|
msg_length += 0x10U - (msg_length & 0xfU);
|
||||||
|
|
||||||
|
char *out = malloc(msg_length);
|
||||||
|
gcry_error_handle = gcry_cipher_encrypt(gcry_cipher_hd, out, msg_length, msg, msg_length);
|
||||||
|
if (gcry_error_handle) {
|
||||||
|
fprintf(stderr, "gcry_cipher_encrypt failed: %s/%s\n",
|
||||||
|
gcry_strsource(gcry_error_handle),
|
||||||
|
gcry_strerror(gcry_error_handle));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
*out_length = msg_length;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// free out buffer after using!
|
||||||
|
char *gcrypt_decrypt_msg(char *msg, size_t msg_length) {
|
||||||
|
if (0U != (msg_length & 0xfU))
|
||||||
|
msg_length += 0x10U - (msg_length & 0xfU);
|
||||||
|
|
||||||
|
char *out_buffer = malloc(msg_length);
|
||||||
|
gcry_error_handle = gcry_cipher_decrypt(gcry_cipher_hd, out_buffer, msg_length, msg, msg_length);
|
||||||
|
if (gcry_error_handle) {
|
||||||
|
fprintf(stderr, "gcry_cipher_encrypt failed: %s/%s\n",
|
||||||
|
gcry_strsource(gcry_error_handle),
|
||||||
|
gcry_strerror(gcry_error_handle));
|
||||||
|
free(out_buffer);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
char *out = malloc(strlen(out_buffer) + 1);
|
||||||
|
strcpy(out, out_buffer);
|
||||||
|
free(out_buffer);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
14
src/include/broadcastsocket.h
Normal file
14
src/include/broadcastsocket.h
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#ifndef __DAWN_BROADCASTSOCKET_H
|
||||||
|
#define __DAWN_BROADCASTSOCKET_H
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function that setups a broadcast socket.
|
||||||
|
* @param _broadcast_ip - The broadcast ip to use.
|
||||||
|
* @param _broadcast_port - The broadcast port to use.
|
||||||
|
* @param addr The sockaddr_in struct.
|
||||||
|
* @return the socket that was created.
|
||||||
|
*/
|
||||||
|
int setup_broadcast_socket(const char *_broadcast_ip, unsigned short _broadcast_port, struct sockaddr_in *addr);
|
||||||
|
|
||||||
|
#endif
|
38
src/include/crypto.h
Normal file
38
src/include/crypto.h
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
#ifndef DAWN_CRYPTO_H
|
||||||
|
#define DAWN_CRYPTO_H
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize gcrypt.
|
||||||
|
* Has to be called before using the other functions!
|
||||||
|
*/
|
||||||
|
void gcrypt_init();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the Key and the iv.
|
||||||
|
* @param key
|
||||||
|
* @param iv
|
||||||
|
*/
|
||||||
|
void gcrypt_set_key_and_iv(const char *key, const char *iv);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function that encrypts the message.
|
||||||
|
* Free the string after using it!
|
||||||
|
* @param msg
|
||||||
|
* @param msg_length
|
||||||
|
* @param out_length
|
||||||
|
* @return the encrypted string.
|
||||||
|
*/
|
||||||
|
char *gcrypt_encrypt_msg(char *msg, size_t msg_length, int *out_length);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FUnction that decrypts a message.
|
||||||
|
* Free the string after using it!
|
||||||
|
* @param msg
|
||||||
|
* @param msg_length
|
||||||
|
* @return the decrypted string.
|
||||||
|
*/
|
||||||
|
char *gcrypt_decrypt_msg(char *msg, size_t msg_length);
|
||||||
|
|
||||||
|
#endif //DAWN_CRYPTO_H
|
267
src/include/datastorage.h
Normal file
267
src/include/datastorage.h
Normal file
|
@ -0,0 +1,267 @@
|
||||||
|
#ifndef __DAWN_DATASTORAGE_H
|
||||||
|
#define __DAWN_DATASTORAGE_H
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <libubox/blobmsg_json.h>
|
||||||
|
|
||||||
|
#ifndef ETH_ALEN
|
||||||
|
#define ETH_ALEN 6
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Mac */
|
||||||
|
|
||||||
|
// ---------------- Defines -------------------
|
||||||
|
#define MAC_LIST_LENGTH 100
|
||||||
|
|
||||||
|
// ---------------- Structs ----------------
|
||||||
|
uint8_t mac_list[MAC_LIST_LENGTH][ETH_ALEN];
|
||||||
|
|
||||||
|
// ---------------- Functions ----------
|
||||||
|
void insert_macs_from_file();
|
||||||
|
|
||||||
|
int insert_to_maclist(uint8_t mac[]);
|
||||||
|
|
||||||
|
int mac_in_maclist(uint8_t mac[]);
|
||||||
|
|
||||||
|
|
||||||
|
/* Metric */
|
||||||
|
|
||||||
|
struct probe_metric_s dawn_metric;
|
||||||
|
|
||||||
|
// ---------------- Structs ----------------
|
||||||
|
struct probe_metric_s {
|
||||||
|
int ap_weight;
|
||||||
|
int ht_support;
|
||||||
|
int vht_support;
|
||||||
|
int no_ht_support;
|
||||||
|
int no_vht_support;
|
||||||
|
int rssi;
|
||||||
|
int low_rssi;
|
||||||
|
int freq;
|
||||||
|
int chan_util;
|
||||||
|
int max_chan_util;
|
||||||
|
int rssi_val;
|
||||||
|
int low_rssi_val;
|
||||||
|
int chan_util_val;
|
||||||
|
int max_chan_util_val;
|
||||||
|
int min_probe_count;
|
||||||
|
int bandwith_threshold;
|
||||||
|
int use_station_count;
|
||||||
|
int max_station_diff;
|
||||||
|
int eval_probe_req;
|
||||||
|
int eval_auth_req;
|
||||||
|
int eval_assoc_req;
|
||||||
|
int deny_auth_reason;
|
||||||
|
int deny_assoc_reason;
|
||||||
|
int use_driver_recog;
|
||||||
|
int min_kick_count;
|
||||||
|
int chan_util_avg_period;
|
||||||
|
int kicking;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct time_config_s {
|
||||||
|
time_t update_client;
|
||||||
|
time_t remove_client;
|
||||||
|
time_t remove_probe;
|
||||||
|
time_t remove_ap;
|
||||||
|
time_t update_hostapd;
|
||||||
|
time_t update_tcp_con;
|
||||||
|
time_t denied_req_threshold;
|
||||||
|
time_t update_chan_util;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct network_config_s {
|
||||||
|
const char *broadcast_ip;
|
||||||
|
int broadcast_port;
|
||||||
|
int tcp_port;
|
||||||
|
int network_option;
|
||||||
|
const char *multicast;
|
||||||
|
const char *shared_key;
|
||||||
|
const char *iv;
|
||||||
|
int bool_multicast;
|
||||||
|
int use_symm_enc;
|
||||||
|
int collision_domain;
|
||||||
|
int bandwidth;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct network_config_s network_config;
|
||||||
|
struct time_config_s timeout_config;
|
||||||
|
|
||||||
|
// ---------------- Global variables ----------------
|
||||||
|
struct probe_metric_s dawn_metric;
|
||||||
|
|
||||||
|
|
||||||
|
/* Probe, Auth, Assoc */
|
||||||
|
|
||||||
|
// ---------------- Structs ----------------
|
||||||
|
typedef struct probe_entry_s {
|
||||||
|
uint8_t bssid_addr[ETH_ALEN];
|
||||||
|
uint8_t client_addr[ETH_ALEN];
|
||||||
|
uint8_t target_addr[ETH_ALEN];
|
||||||
|
uint32_t signal;
|
||||||
|
uint32_t freq;
|
||||||
|
uint8_t ht_capabilities;
|
||||||
|
uint8_t vht_capabilities;
|
||||||
|
time_t time;
|
||||||
|
int counter;
|
||||||
|
int deny_counter;
|
||||||
|
uint8_t max_supp_datarate;
|
||||||
|
uint8_t min_supp_datarate;
|
||||||
|
} probe_entry;
|
||||||
|
|
||||||
|
typedef struct auth_entry_s {
|
||||||
|
uint8_t bssid_addr[ETH_ALEN];
|
||||||
|
uint8_t client_addr[ETH_ALEN];
|
||||||
|
uint8_t target_addr[ETH_ALEN];
|
||||||
|
uint32_t signal;
|
||||||
|
uint32_t freq;
|
||||||
|
time_t time;
|
||||||
|
int counter;
|
||||||
|
} auth_entry;
|
||||||
|
|
||||||
|
typedef struct hostapd_notify_entry_s {
|
||||||
|
uint8_t bssid_addr[ETH_ALEN];
|
||||||
|
uint8_t client_addr[ETH_ALEN];
|
||||||
|
} hostapd_notify_entry;
|
||||||
|
|
||||||
|
typedef struct auth_entry_s assoc_entry;
|
||||||
|
|
||||||
|
#define DENY_REQ_ARRAY_LEN 100
|
||||||
|
struct auth_entry_s denied_req_array[DENY_REQ_ARRAY_LEN];
|
||||||
|
pthread_mutex_t denied_array_mutex;
|
||||||
|
|
||||||
|
auth_entry insert_to_denied_req_array(auth_entry entry, int inc_counter);
|
||||||
|
|
||||||
|
// ---------------- Defines ----------------
|
||||||
|
#define PROBE_ARRAY_LEN 1000
|
||||||
|
|
||||||
|
#define SSID_MAX_LEN 32
|
||||||
|
|
||||||
|
// ---------------- Global variables ----------------
|
||||||
|
struct probe_entry_s probe_array[PROBE_ARRAY_LEN];
|
||||||
|
pthread_mutex_t probe_array_mutex;
|
||||||
|
|
||||||
|
// ---------------- Functions ----------------
|
||||||
|
probe_entry insert_to_array(probe_entry entry, int inc_counter);
|
||||||
|
|
||||||
|
void probe_array_insert(probe_entry entry);
|
||||||
|
|
||||||
|
probe_entry probe_array_delete(probe_entry entry);
|
||||||
|
|
||||||
|
probe_entry probe_array_get_entry(uint8_t bssid_addr[], uint8_t client_addr[]);
|
||||||
|
|
||||||
|
void print_probe_array();
|
||||||
|
|
||||||
|
void print_probe_entry(probe_entry entry);
|
||||||
|
|
||||||
|
void print_auth_entry(auth_entry entry);
|
||||||
|
|
||||||
|
void uloop_add_data_cbs();
|
||||||
|
|
||||||
|
/* AP, Client */
|
||||||
|
|
||||||
|
// blobmsg_alloc_string_buffer(&b, "signature", 1024);
|
||||||
|
#define SIGNATURE_LEN 1024
|
||||||
|
|
||||||
|
// ---------------- Structs ----------------
|
||||||
|
typedef struct client_s {
|
||||||
|
uint8_t bssid_addr[ETH_ALEN];
|
||||||
|
uint8_t client_addr[ETH_ALEN];
|
||||||
|
char signature[SIGNATURE_LEN];
|
||||||
|
uint8_t ht_supported;
|
||||||
|
uint8_t vht_supported;
|
||||||
|
uint32_t freq;
|
||||||
|
uint8_t auth;
|
||||||
|
uint8_t assoc;
|
||||||
|
uint8_t authorized;
|
||||||
|
uint8_t preauth;
|
||||||
|
uint8_t wds;
|
||||||
|
uint8_t wmm;
|
||||||
|
uint8_t ht;
|
||||||
|
uint8_t vht;
|
||||||
|
uint8_t wps;
|
||||||
|
uint8_t mfp;
|
||||||
|
time_t time;
|
||||||
|
uint32_t aid;
|
||||||
|
uint32_t kick_count;
|
||||||
|
} client;
|
||||||
|
|
||||||
|
typedef struct ap_s {
|
||||||
|
uint8_t bssid_addr[ETH_ALEN];
|
||||||
|
uint32_t freq;
|
||||||
|
uint8_t ht_support;
|
||||||
|
uint8_t vht_support;
|
||||||
|
uint32_t channel_utilization;
|
||||||
|
time_t time;
|
||||||
|
uint32_t station_count;
|
||||||
|
uint8_t ssid[SSID_MAX_LEN];
|
||||||
|
uint32_t collision_domain;
|
||||||
|
uint32_t bandwidth;
|
||||||
|
uint32_t ap_weight;
|
||||||
|
} ap;
|
||||||
|
|
||||||
|
// ---------------- Defines ----------------
|
||||||
|
#define ARRAY_AP_LEN 50
|
||||||
|
#define TIME_THRESHOLD_AP 30
|
||||||
|
#define ARRAY_CLIENT_LEN 1000
|
||||||
|
#define TIME_THRESHOLD_CLIENT 30
|
||||||
|
#define TIME_THRESHOLD_CLIENT_UPDATE 10
|
||||||
|
#define TIME_THRESHOLD_CLIENT_KICK 60
|
||||||
|
|
||||||
|
// ---------------- Global variables ----------------
|
||||||
|
struct client_s client_array[ARRAY_CLIENT_LEN];
|
||||||
|
pthread_mutex_t client_array_mutex;
|
||||||
|
struct ap_s ap_array[ARRAY_AP_LEN];
|
||||||
|
pthread_mutex_t ap_array_mutex;
|
||||||
|
|
||||||
|
int mac_is_equal(uint8_t addr1[], uint8_t addr2[]);
|
||||||
|
|
||||||
|
int mac_is_greater(uint8_t addr1[], uint8_t addr2[]);
|
||||||
|
|
||||||
|
// ---------------- Functions ----------------
|
||||||
|
|
||||||
|
void insert_client_to_array(client entry);
|
||||||
|
|
||||||
|
void kick_clients(uint8_t bssid[], uint32_t id);
|
||||||
|
|
||||||
|
void client_array_insert(client entry);
|
||||||
|
|
||||||
|
client client_array_delete(client entry);
|
||||||
|
|
||||||
|
void print_client_array();
|
||||||
|
|
||||||
|
void print_client_entry(client entry);
|
||||||
|
|
||||||
|
ap insert_to_ap_array(ap entry);
|
||||||
|
|
||||||
|
void print_ap_array();
|
||||||
|
|
||||||
|
ap ap_array_get_ap(uint8_t bssid_addr[]);
|
||||||
|
|
||||||
|
int build_hearing_map_sort_client(struct blob_buf *b);
|
||||||
|
|
||||||
|
int build_network_overview(struct blob_buf *b);
|
||||||
|
|
||||||
|
int probe_array_set_all_probe_count(uint8_t client_addr[], uint32_t probe_count);
|
||||||
|
|
||||||
|
int ap_get_collision_count(int col_domain);
|
||||||
|
|
||||||
|
/* Utils */
|
||||||
|
|
||||||
|
// ---------------- Defines -------------------
|
||||||
|
#define SORT_NUM 5
|
||||||
|
|
||||||
|
// ---------------- Global variables ----------------
|
||||||
|
char *sort_string;
|
||||||
|
|
||||||
|
// ---------------- Functions -------------------
|
||||||
|
int better_ap_available(uint8_t bssid_addr[], uint8_t client_addr[], int automatic_kick);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
68
src/include/dawn_iwinfo.h
Normal file
68
src/include/dawn_iwinfo.h
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
#ifndef DAWN_RSSI_H
|
||||||
|
#define DAWN_RSSI_H
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get RSSI using the mac adress of the client.
|
||||||
|
* Function uses libiwinfo and searches through all interfaces that are existing.
|
||||||
|
* @param client_addr - mac adress of the client
|
||||||
|
* @return The RSSI of the client if successful. INT_MIN if client was not found.
|
||||||
|
*/
|
||||||
|
int get_rssi_iwinfo(__uint8_t *client_addr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get expected throughut using the mac adress of the client.
|
||||||
|
* Function uses libiwinfo and searches through all interfaces that are existing.
|
||||||
|
* @param client_addr - mac adress of the client
|
||||||
|
* @return
|
||||||
|
* + The expected throughput of the client if successful.
|
||||||
|
* + INT_MIN if client was not found.
|
||||||
|
* + 0 if the client is not supporting this feature.
|
||||||
|
*/
|
||||||
|
int get_expected_throughput_iwinfo(uint8_t *client_addr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get rx and tx bandwidth using the mac of the client.
|
||||||
|
* Function uses libiwinfo and searches through all interfaces that are existing.
|
||||||
|
* @param client_addr - mac adress of the client
|
||||||
|
* @param rx_rate - float pointer for returning the rx rate
|
||||||
|
* @param tx_rate - float pointer for returning the tx rate
|
||||||
|
* @return 0 if successful 1 otherwise.
|
||||||
|
*/
|
||||||
|
int get_bandwidth_iwinfo(__uint8_t *client_addr, float *rx_rate, float *tx_rate);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function checks if two bssid adresses have the same essid.
|
||||||
|
* Function uses libiwinfo and searches through all interfaces that are existing.
|
||||||
|
* @param bssid_addr
|
||||||
|
* @param bssid_addr_to_compares
|
||||||
|
* @return 1 if the bssid adresses have the same essid.
|
||||||
|
*/
|
||||||
|
int compare_essid_iwinfo(__uint8_t *bssid_addr, __uint8_t *bssid_addr_to_compare);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function returns the expected throughput using the interface and the client address.
|
||||||
|
* @param ifname
|
||||||
|
* @param client_addr
|
||||||
|
* @return
|
||||||
|
* + The expected throughput of the client if successful.
|
||||||
|
* + INT_MIN if client was not found.
|
||||||
|
* + 0 if the client is not supporting this feature.
|
||||||
|
*/
|
||||||
|
int get_expected_throughput(const char *ifname, uint8_t *client_addr);
|
||||||
|
|
||||||
|
int get_bssid(const char *ifname, uint8_t *bssid_addr);
|
||||||
|
|
||||||
|
int get_ssid(const char *ifname, char *ssid);
|
||||||
|
|
||||||
|
int get_channel_utilization(const char *ifname, uint64_t *last_channel_time, uint64_t *last_channel_time_busy);
|
||||||
|
|
||||||
|
int support_ht(const char *ifname);
|
||||||
|
|
||||||
|
int support_vht(const char *ifname);
|
||||||
|
|
||||||
|
#endif //DAWN_RSSI_H
|
50
src/include/dawn_uci.h
Normal file
50
src/include/dawn_uci.h
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
#ifndef DAWN_UCI_H
|
||||||
|
#define DAWN_UCI_H
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Init uci. Call this function before using the other functions!
|
||||||
|
* @return if call was successful.
|
||||||
|
*/
|
||||||
|
int uci_init();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear uci. Call this function after using uci!
|
||||||
|
* @return if call was successful.
|
||||||
|
*/
|
||||||
|
int uci_clear();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function that returns the metric for the load balancing sheme using uci.
|
||||||
|
* @return the load balancing metric.
|
||||||
|
*/
|
||||||
|
struct probe_metric_s uci_get_dawn_metric();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function that returns a struct with all the time config values.
|
||||||
|
* @return the time config values.
|
||||||
|
*/
|
||||||
|
struct time_config_s uci_get_time_config();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function that returns all the network informations.
|
||||||
|
* @return the network config values.
|
||||||
|
*/
|
||||||
|
struct network_config_s uci_get_dawn_network();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function that returns the hostapd directory reading from the config file.
|
||||||
|
* @return the hostapd directory.
|
||||||
|
*/
|
||||||
|
const char *uci_get_dawn_hostapd_dir();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function that returns the sort order.
|
||||||
|
* @return the sort order.
|
||||||
|
*/
|
||||||
|
const char *uci_get_dawn_sort_order();
|
||||||
|
|
||||||
|
int uci_set_network(char* uci_cmd);
|
||||||
|
|
||||||
|
int uci_reset();
|
||||||
|
|
||||||
|
#endif //DAWN_UCI_H_H
|
20
src/include/ieee80211_utils.h
Normal file
20
src/include/ieee80211_utils.h
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
#ifndef DAWN_IEEE80211_UTILS_H
|
||||||
|
#define DAWN_IEEE80211_UTILS_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate bitrate using the supported rates values.
|
||||||
|
* @param supp_rate_val
|
||||||
|
* @return the bitrate.
|
||||||
|
*/
|
||||||
|
double iee80211_calculate_bitrate(uint8_t supp_rate_val);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate expected throughput in Mbit/sec.
|
||||||
|
* @param exp_thr
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
double iee80211_calculate_expected_throughput_mbit(int exp_thr);
|
||||||
|
|
||||||
|
#endif //DAWN_IEEE80211_UTILS_H
|
21
src/include/multicastsocket.h
Normal file
21
src/include/multicastsocket.h
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
#ifndef __DAWN_MULTICASTSTSOCKET_H
|
||||||
|
#define __DAWN_MULTICASTSSOCKET_H
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup a multicast socket.
|
||||||
|
* Setup permissions. Join the multicast group, etc. ...
|
||||||
|
* @param _multicast_ip - multicast ip to use.
|
||||||
|
* @param _multicast_port - multicast port to use.
|
||||||
|
* @param addr
|
||||||
|
* @return the multicast socket.
|
||||||
|
*/
|
||||||
|
int setup_multicast_socket(const char *_multicast_ip, unsigned short _multicast_port, struct sockaddr_in *addr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the multicast socket.
|
||||||
|
* @param socket
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
int remove_multicast_socket(int socket);
|
||||||
|
|
||||||
|
#endif
|
39
src/include/networksocket.h
Normal file
39
src/include/networksocket.h
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
#ifndef __DAWN_NETWORKSOCKET_H
|
||||||
|
#define __DAWN_NETWORKSOCKET_H
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
pthread_mutex_t send_mutex;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Init a socket using the runopts.
|
||||||
|
* @param _ip - ip to use.
|
||||||
|
* @param _port - port to use.
|
||||||
|
* @param _multicast_socket - if socket should be multicast or broadcast.
|
||||||
|
* @return the socket.
|
||||||
|
*/
|
||||||
|
int init_socket_runopts(const char *_ip, int _port, int _multicast_socket);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send message via network.
|
||||||
|
* @param msg
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
int send_string(char *msg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send encrypted message via network.
|
||||||
|
* @param msg
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
int send_string_enc(char *msg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close socket.
|
||||||
|
*/
|
||||||
|
void close_socket();
|
||||||
|
|
||||||
|
// save connections
|
||||||
|
// struct sockaddr_in addr[100];
|
||||||
|
|
||||||
|
#endif
|
46
src/include/tcpsocket.h
Normal file
46
src/include/tcpsocket.h
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
#ifndef DAWN_TCPSOCKET_H
|
||||||
|
#define DAWN_TCPSOCKET_H
|
||||||
|
|
||||||
|
#include <libubox/ustream.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#define ARRAY_NETWORK_LEN 50
|
||||||
|
|
||||||
|
struct network_con_s {
|
||||||
|
struct list_head list;
|
||||||
|
|
||||||
|
struct uloop_fd fd;
|
||||||
|
struct ustream_fd stream;
|
||||||
|
struct sockaddr_in sock_addr;
|
||||||
|
int connected;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add tcp connection.
|
||||||
|
* @param ipv4
|
||||||
|
* @param port
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
int add_tcp_conncection(char *ipv4, int port);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens a tcp server and adds it to the uloop.
|
||||||
|
* @param port
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
int run_server(int port);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send message via tcp to all other hosts.
|
||||||
|
* @param msg
|
||||||
|
*/
|
||||||
|
void send_tcp(char *msg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Debug message.
|
||||||
|
*/
|
||||||
|
void print_tcp_array();
|
||||||
|
|
||||||
|
|
||||||
|
#endif //DAWN_TCPSOCKET_H
|
165
src/include/ubus.h
Normal file
165
src/include/ubus.h
Normal file
|
@ -0,0 +1,165 @@
|
||||||
|
#ifndef __DAWN_UBUS_H
|
||||||
|
#define __DAWN_UBUS_H
|
||||||
|
|
||||||
|
#include <libubox/blobmsg_json.h>
|
||||||
|
#include <libubox/uloop.h>
|
||||||
|
|
||||||
|
#include "datastorage.h"
|
||||||
|
|
||||||
|
// 802.11 Status codes
|
||||||
|
#define WLAN_STATUS_SUCCESS 0
|
||||||
|
#define WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA 17
|
||||||
|
#define WLAN_STATUS_DENIED_NOT_HT_SUPPORT 27
|
||||||
|
#define WLAN_STATUS_DENIED_NOT_VHT_SUPPORT 104
|
||||||
|
|
||||||
|
// Disassociation Reason
|
||||||
|
#define UNSPECIFIED_REASON 0
|
||||||
|
#define NO_MORE_STAS 5
|
||||||
|
|
||||||
|
const char *hostapd_dir_glob;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Init ubus.
|
||||||
|
* Setup tcp socket.
|
||||||
|
* Start ubus timer.
|
||||||
|
* @param ubus_socket
|
||||||
|
* @param hostapd_dir
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
int dawn_init_ubus(const char *ubus_socket, const char *hostapd_dir);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start the umdns timer for updating the zeroconfiguration properties.
|
||||||
|
*/
|
||||||
|
void start_umdns_update();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call umdns update to update the TCP connections.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
int ubus_call_umdns();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse to probe request.
|
||||||
|
* @param msg
|
||||||
|
* @param prob_req
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
int parse_to_probe_req(struct blob_attr *msg, probe_entry *prob_req);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse to authentication request.
|
||||||
|
* @param msg
|
||||||
|
* @param auth_req
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
int parse_to_auth_req(struct blob_attr *msg, auth_entry *auth_req);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse to association request.
|
||||||
|
* @param msg
|
||||||
|
* @param assoc_req
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
int parse_to_assoc_req(struct blob_attr *msg, assoc_entry *assoc_req);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dump a client array into the database.
|
||||||
|
* @param msg - message to parse.
|
||||||
|
* @param do_kick - use the automatic kick function when updating the clients.
|
||||||
|
* @param id - ubus id.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
int parse_to_clients(struct blob_attr *msg, int do_kick, uint32_t id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse to hostapd notify.
|
||||||
|
* Notify are such notifications like:
|
||||||
|
* + Disassociation
|
||||||
|
* + Deauthentication
|
||||||
|
* + ...
|
||||||
|
* @param msg
|
||||||
|
* @param notify_req
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
int parse_to_hostapd_notify(struct blob_attr *msg, hostapd_notify_entry *notify_req);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Kick client from hostapd interface.
|
||||||
|
* @param id - the ubus id.
|
||||||
|
* @param client_addr - the client adress of the client to kick.
|
||||||
|
* @param reason - the reason to kick the client.
|
||||||
|
* @param deauth - if the client should be deauthenticated.
|
||||||
|
* @param ban_time - the ban time the client is not allowed to connect again.
|
||||||
|
*/
|
||||||
|
void del_client_interface(uint32_t id, const uint8_t *client_addr, uint32_t reason, uint8_t deauth, uint32_t ban_time);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Kick client from all hostapd interfaces.
|
||||||
|
* @param client_addr - the client adress of the client to kick.
|
||||||
|
* @param reason - the reason to kick the client.
|
||||||
|
* @param deauth - if the client should be deauthenticated.
|
||||||
|
* @param ban_time - the ban time the client is not allowed to connect again.
|
||||||
|
*/
|
||||||
|
void del_client_all_interfaces(const uint8_t *client_addr, uint32_t reason, uint8_t deauth, uint32_t ban_time);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send probe message via the network.
|
||||||
|
* @param probe_entry
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
int ubus_send_probe_via_network(struct probe_entry_s probe_entry);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the hostapd sockets.
|
||||||
|
* @param t
|
||||||
|
*/
|
||||||
|
void update_hostapd_sockets(struct uloop_timeout *t);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set client timer for updating the clients.
|
||||||
|
* @param time
|
||||||
|
*/
|
||||||
|
void add_client_update_timer(time_t time);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle network messages.
|
||||||
|
* @param msg
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
int handle_network_msg(char *msg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send message via network.
|
||||||
|
* @param msg
|
||||||
|
* @param method
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
int send_blob_attr_via_network(struct blob_attr *msg, char *method);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add mac to a list that contains addresses of clients that can not be controlled.
|
||||||
|
* @param buf
|
||||||
|
* @param name
|
||||||
|
* @param addr
|
||||||
|
*/
|
||||||
|
void blobmsg_add_macaddr(struct blob_buf *buf, const char *name, const uint8_t *addr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to set the probe counter to the min probe request.
|
||||||
|
* This allows that the client is able to connect directly without sending multiple probe requests to the Access Point.
|
||||||
|
* @param client_addr
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
int send_set_probe(uint8_t client_addr[]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send control message to all hosts to add the mac to a don't control list.
|
||||||
|
* @param client_addr
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
int send_add_mac(uint8_t *client_addr);
|
||||||
|
|
||||||
|
int uci_send_via_network();
|
||||||
|
|
||||||
|
#endif
|
50
src/include/utils.h
Normal file
50
src/include/utils.h
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
#ifndef __DAWN_UTILS_H
|
||||||
|
#define __DAWN_UTILS_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
|
||||||
|
#define STR2MAC(a) &(a)[0], &(a)[1], &(a)[2], &(a)[3], &(a)[4], &(a)[5]
|
||||||
|
|
||||||
|
#define MACSTR "%02X:%02X:%02X:%02X:%02X:%02X"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert char to binary.
|
||||||
|
* @param ch
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
int hex_to_bin(char ch);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert mac adress string to mac adress.
|
||||||
|
* @param txt
|
||||||
|
* @param addr
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
int hwaddr_aton(const char *txt, uint8_t *addr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert mac to use big characters.
|
||||||
|
* @param in
|
||||||
|
* @param out
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
int convert_mac(char *in, char *out);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write mac to a file.
|
||||||
|
* @param path
|
||||||
|
* @param addr
|
||||||
|
*/
|
||||||
|
void write_mac_to_file(char *path, uint8_t addr[]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a string is greater than another one.
|
||||||
|
* @param str
|
||||||
|
* @param str_2
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
int string_is_greater(uint8_t *str, uint8_t *str_2);
|
||||||
|
|
||||||
|
#endif
|
122
src/main.c
Normal file
122
src/main.c
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
#include <libubus.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "datastorage.h"
|
||||||
|
#include "networksocket.h"
|
||||||
|
#include "ubus.h"
|
||||||
|
#include "dawn_uci.h"
|
||||||
|
#include "tcpsocket.h"
|
||||||
|
#include "crypto.h"
|
||||||
|
|
||||||
|
void daemon_shutdown();
|
||||||
|
|
||||||
|
void signal_handler(int sig);
|
||||||
|
|
||||||
|
int init_mutex();
|
||||||
|
|
||||||
|
struct sigaction signal_action;
|
||||||
|
|
||||||
|
void daemon_shutdown() {
|
||||||
|
// kill threads
|
||||||
|
close_socket();
|
||||||
|
uci_clear();
|
||||||
|
uloop_cancelled = true;
|
||||||
|
|
||||||
|
// free ressources
|
||||||
|
fprintf(stdout, "Freeing mutex ressources\n");
|
||||||
|
pthread_mutex_destroy(&probe_array_mutex);
|
||||||
|
pthread_mutex_destroy(&client_array_mutex);
|
||||||
|
pthread_mutex_destroy(&ap_array_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void signal_handler(int sig) {
|
||||||
|
switch (sig) {
|
||||||
|
case SIGHUP:
|
||||||
|
daemon_shutdown();
|
||||||
|
break;
|
||||||
|
case SIGINT:
|
||||||
|
daemon_shutdown();
|
||||||
|
break;
|
||||||
|
case SIGTERM:
|
||||||
|
daemon_shutdown();
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
default:
|
||||||
|
daemon_shutdown();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int init_mutex() {
|
||||||
|
|
||||||
|
if (pthread_mutex_init(&probe_array_mutex, NULL) != 0) {
|
||||||
|
fprintf(stderr, "Mutex init failed!\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pthread_mutex_init(&client_array_mutex, NULL) != 0) {
|
||||||
|
fprintf(stderr, "Mutex init failed!\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pthread_mutex_init(&ap_array_mutex, NULL) != 0) {
|
||||||
|
fprintf(stderr, "Mutex init failed!\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pthread_mutex_init(&denied_array_mutex, NULL) != 0) {
|
||||||
|
fprintf(stderr, "Mutex init failed!\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
|
||||||
|
const char *ubus_socket = NULL;
|
||||||
|
|
||||||
|
argc -= optind;
|
||||||
|
argv += optind;
|
||||||
|
|
||||||
|
// connect signals
|
||||||
|
signal_action.sa_handler = signal_handler;
|
||||||
|
sigemptyset(&signal_action.sa_mask);
|
||||||
|
signal_action.sa_flags = 0;
|
||||||
|
sigaction(SIGHUP, &signal_action, NULL);
|
||||||
|
sigaction(SIGTERM, &signal_action, NULL);
|
||||||
|
sigaction(SIGINT, &signal_action, NULL);
|
||||||
|
|
||||||
|
uci_init();
|
||||||
|
struct network_config_s net_config = uci_get_dawn_network();
|
||||||
|
network_config = net_config;
|
||||||
|
|
||||||
|
// init crypto
|
||||||
|
gcrypt_init();
|
||||||
|
gcrypt_set_key_and_iv(net_config.shared_key, net_config.iv);
|
||||||
|
|
||||||
|
struct time_config_s time_config = uci_get_time_config();
|
||||||
|
timeout_config = time_config; // TODO: Refactor...
|
||||||
|
|
||||||
|
hostapd_dir_glob = uci_get_dawn_hostapd_dir();
|
||||||
|
sort_string = (char *) uci_get_dawn_sort_order();
|
||||||
|
|
||||||
|
init_mutex();
|
||||||
|
|
||||||
|
switch (net_config.network_option) {
|
||||||
|
case 0:
|
||||||
|
init_socket_runopts(net_config.broadcast_ip, net_config.broadcast_port, 0);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
init_socket_runopts(net_config.broadcast_ip, net_config.broadcast_port, 1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
insert_macs_from_file();
|
||||||
|
dawn_init_ubus(ubus_socket, hostapd_dir_glob);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
41
src/network/broadcastsocket.c
Normal file
41
src/network/broadcastsocket.c
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "networksocket.h"
|
||||||
|
#include "broadcastsocket.h"
|
||||||
|
|
||||||
|
int setup_broadcast_socket(const char *_broadcast_ip, unsigned short _broadcast_port, struct sockaddr_in *addr) {
|
||||||
|
int sock;
|
||||||
|
int broadcast_permission;
|
||||||
|
|
||||||
|
// Create socket
|
||||||
|
if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
|
||||||
|
fprintf(stderr, "Failed to create socket.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allow broadcast
|
||||||
|
broadcast_permission = 1;
|
||||||
|
if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (void *) &broadcast_permission,
|
||||||
|
sizeof(broadcast_permission)) < 0) {
|
||||||
|
fprintf(stderr, "Failed to create socket.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Constract addess
|
||||||
|
memset(addr, 0, sizeof(*addr));
|
||||||
|
addr->sin_family = AF_INET;
|
||||||
|
addr->sin_addr.s_addr = inet_addr(_broadcast_ip);
|
||||||
|
addr->sin_port = htons(_broadcast_port);
|
||||||
|
|
||||||
|
// Bind socket
|
||||||
|
while (bind(sock, (struct sockaddr *) addr, sizeof(*addr)) < 0) {
|
||||||
|
fprintf(stderr, "Binding socket failed!\n");
|
||||||
|
sleep(1);
|
||||||
|
}
|
||||||
|
return sock;
|
||||||
|
}
|
83
src/network/multicastsocket.c
Normal file
83
src/network/multicastsocket.c
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "multicastsocket.h"
|
||||||
|
|
||||||
|
// based on: http://openbook.rheinwerk-verlag.de/linux_unix_programmierung/Kap11-018.htm
|
||||||
|
|
||||||
|
static struct ip_mreq command;
|
||||||
|
|
||||||
|
int setup_multicast_socket(const char *_multicast_ip, unsigned short _multicast_port, struct sockaddr_in *addr) {
|
||||||
|
int loop = 1;
|
||||||
|
int sock;
|
||||||
|
|
||||||
|
memset(addr, 0, sizeof(*addr));
|
||||||
|
addr->sin_family = AF_INET;
|
||||||
|
addr->sin_addr.s_addr = inet_addr(_multicast_ip);
|
||||||
|
addr->sin_port = htons (_multicast_port);
|
||||||
|
|
||||||
|
if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) == -1) {
|
||||||
|
perror("socket()");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// allow multiple processes to use the same port
|
||||||
|
loop = 1;
|
||||||
|
if (setsockopt(sock,
|
||||||
|
SOL_SOCKET,
|
||||||
|
SO_REUSEADDR,
|
||||||
|
&loop, sizeof(loop)) < 0) {
|
||||||
|
perror("setsockopt:SO_REUSEADDR");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
if (bind(sock,
|
||||||
|
(struct sockaddr *) addr,
|
||||||
|
sizeof(*addr)) < 0) {
|
||||||
|
perror("bind");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// allow broadcast
|
||||||
|
loop = 1;
|
||||||
|
if (setsockopt(sock,
|
||||||
|
IPPROTO_IP,
|
||||||
|
IP_MULTICAST_LOOP,
|
||||||
|
&loop, sizeof(loop)) < 0) {
|
||||||
|
perror("setsockopt:IP_MULTICAST_LOOP");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// join broadcast group
|
||||||
|
command.imr_multiaddr.s_addr = inet_addr(_multicast_ip);
|
||||||
|
command.imr_interface.s_addr = htonl (INADDR_ANY);
|
||||||
|
if (command.imr_multiaddr.s_addr == -1) {
|
||||||
|
perror("Wrong multicast address!\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
if (setsockopt(sock,
|
||||||
|
IPPROTO_IP,
|
||||||
|
IP_ADD_MEMBERSHIP,
|
||||||
|
&command, sizeof(command)) < 0) {
|
||||||
|
perror("setsockopt:IP_ADD_MEMBERSHIP");
|
||||||
|
}
|
||||||
|
return sock;
|
||||||
|
}
|
||||||
|
|
||||||
|
int remove_multicast_socket(int socket) {
|
||||||
|
if (setsockopt(socket,
|
||||||
|
IPPROTO_IP,
|
||||||
|
IP_DROP_MEMBERSHIP,
|
||||||
|
&command, sizeof(command)) < 0) {
|
||||||
|
perror("setsockopt:IP_DROP_MEMBERSHIP");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
162
src/network/networksocket.c
Normal file
162
src/network/networksocket.c
Normal file
|
@ -0,0 +1,162 @@
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <libubox/blobmsg_json.h>
|
||||||
|
|
||||||
|
#include "networksocket.h"
|
||||||
|
#include "datastorage.h"
|
||||||
|
#include "multicastsocket.h"
|
||||||
|
#include "broadcastsocket.h"
|
||||||
|
#include "ubus.h"
|
||||||
|
#include "crypto.h"
|
||||||
|
|
||||||
|
/* Network Defines */
|
||||||
|
#define MAX_RECV_STRING 2048
|
||||||
|
|
||||||
|
/* Network Attributes */
|
||||||
|
int sock;
|
||||||
|
struct sockaddr_in addr;
|
||||||
|
const char *ip;
|
||||||
|
unsigned short port;
|
||||||
|
char recv_string[MAX_RECV_STRING + 1];
|
||||||
|
int recv_string_len;
|
||||||
|
int multicast_socket;
|
||||||
|
|
||||||
|
void *receive_msg(void *args);
|
||||||
|
|
||||||
|
void *receive_msg_enc(void *args);
|
||||||
|
|
||||||
|
int init_socket_runopts(const char *_ip, int _port, int _multicast_socket) {
|
||||||
|
|
||||||
|
port = _port;
|
||||||
|
ip = _ip;
|
||||||
|
multicast_socket = _multicast_socket;
|
||||||
|
|
||||||
|
if (multicast_socket) {
|
||||||
|
printf("Settingup multicastsocket!\n");
|
||||||
|
sock = setup_multicast_socket(ip, port, &addr);
|
||||||
|
} else {
|
||||||
|
sock = setup_broadcast_socket(ip, port, &addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_t sniffer_thread;
|
||||||
|
if (network_config.use_symm_enc) {
|
||||||
|
if (pthread_create(&sniffer_thread, NULL, receive_msg_enc, NULL)) {
|
||||||
|
fprintf(stderr, "Could not create receiving thread!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (pthread_create(&sniffer_thread, NULL, receive_msg, NULL)) {
|
||||||
|
fprintf(stderr, "Could not create receiving thread!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stdout, "Connected to %s:%d\n", ip, port);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *receive_msg(void *args) {
|
||||||
|
while (1) {
|
||||||
|
if ((recv_string_len =
|
||||||
|
recvfrom(sock, recv_string, MAX_RECV_STRING, 0, NULL, 0)) < 0) {
|
||||||
|
fprintf(stderr, "Could not receive message!");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (recv_string == NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strlen(recv_string) <= 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
recv_string[recv_string_len] = '\0';
|
||||||
|
|
||||||
|
printf("Received network message: %s\n", recv_string);
|
||||||
|
handle_network_msg(recv_string);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void *receive_msg_enc(void *args) {
|
||||||
|
while (1) {
|
||||||
|
if ((recv_string_len =
|
||||||
|
recvfrom(sock, recv_string, MAX_RECV_STRING, 0, NULL, 0)) < 0) {
|
||||||
|
fprintf(stderr, "Could not receive message!\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (recv_string == NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strlen(recv_string) <= 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
recv_string[recv_string_len] = '\0';
|
||||||
|
|
||||||
|
char *base64_dec_str = malloc(B64_DECODE_LEN(strlen(recv_string)));
|
||||||
|
int base64_dec_length = b64_decode(recv_string, base64_dec_str, B64_DECODE_LEN(strlen(recv_string)));
|
||||||
|
char *dec = gcrypt_decrypt_msg(base64_dec_str, base64_dec_length);
|
||||||
|
|
||||||
|
printf("Received network message: %s\n", dec);
|
||||||
|
free(base64_dec_str);
|
||||||
|
handle_network_msg(dec);
|
||||||
|
free(dec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int send_string(char *msg) {
|
||||||
|
pthread_mutex_lock(&send_mutex);
|
||||||
|
size_t msglen = strlen(msg);
|
||||||
|
|
||||||
|
if (sendto(sock,
|
||||||
|
msg,
|
||||||
|
msglen,
|
||||||
|
0,
|
||||||
|
(struct sockaddr *) &addr,
|
||||||
|
sizeof(addr)) < 0) {
|
||||||
|
perror("sendto()");
|
||||||
|
pthread_mutex_unlock(&send_mutex);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&send_mutex);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int send_string_enc(char *msg) {
|
||||||
|
pthread_mutex_lock(&send_mutex);
|
||||||
|
|
||||||
|
int length_enc;
|
||||||
|
size_t msglen = strlen(msg);
|
||||||
|
char *enc = gcrypt_encrypt_msg(msg, msglen + 1, &length_enc);
|
||||||
|
|
||||||
|
char *base64_enc_str = malloc(B64_ENCODE_LEN(length_enc));
|
||||||
|
size_t base64_enc_length = b64_encode(enc, length_enc, base64_enc_str, B64_ENCODE_LEN(length_enc));
|
||||||
|
|
||||||
|
if (sendto(sock,
|
||||||
|
base64_enc_str,
|
||||||
|
base64_enc_length, // very important to use actual length of string because of '\0' in encrypted msg
|
||||||
|
0,
|
||||||
|
(struct sockaddr *) &addr,
|
||||||
|
sizeof(addr)) < 0) {
|
||||||
|
perror("sendto()");
|
||||||
|
pthread_mutex_unlock(&send_mutex);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
free(base64_enc_str);
|
||||||
|
free(enc);
|
||||||
|
pthread_mutex_unlock(&send_mutex);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void close_socket() {
|
||||||
|
if (multicast_socket) {
|
||||||
|
remove_multicast_socket(sock);
|
||||||
|
}
|
||||||
|
close(sock);
|
||||||
|
}
|
288
src/network/tcpsocket.c
Normal file
288
src/network/tcpsocket.c
Normal file
|
@ -0,0 +1,288 @@
|
||||||
|
#include <libubox/usock.h>
|
||||||
|
#include <libubox/ustream.h>
|
||||||
|
#include <libubox/uloop.h>
|
||||||
|
#include <libubox/utils.h> // base64 encoding
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "tcpsocket.h"
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include "ubus.h"
|
||||||
|
#include "crypto.h"
|
||||||
|
|
||||||
|
LIST_HEAD(tcp_sock_list);
|
||||||
|
|
||||||
|
struct network_con_s *tcp_list_contains_address(struct sockaddr_in entry);
|
||||||
|
|
||||||
|
static struct uloop_fd server;
|
||||||
|
struct client *next_client = NULL;
|
||||||
|
|
||||||
|
struct client {
|
||||||
|
struct sockaddr_in sin;
|
||||||
|
|
||||||
|
struct ustream_fd s;
|
||||||
|
int ctr;
|
||||||
|
int counter;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void client_close(struct ustream *s) {
|
||||||
|
struct client *cl = container_of(s,
|
||||||
|
struct client, s.stream);
|
||||||
|
|
||||||
|
fprintf(stderr, "Connection closed\n");
|
||||||
|
ustream_free(s);
|
||||||
|
close(cl->s.fd.fd);
|
||||||
|
free(cl);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void client_notify_write(struct ustream *s, int bytes) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void client_notify_state(struct ustream *s) {
|
||||||
|
struct client *cl = container_of(s,
|
||||||
|
struct client, s.stream);
|
||||||
|
|
||||||
|
if (!s->eof)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fprintf(stderr, "eof!, pending: %d, total: %d\n", s->w.data_bytes, cl->ctr);
|
||||||
|
|
||||||
|
if (!s->w.data_bytes)
|
||||||
|
return client_close(s);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void client_to_server_close(struct ustream *s) {
|
||||||
|
struct network_con_s *con = container_of(s,
|
||||||
|
struct network_con_s, stream.stream);
|
||||||
|
|
||||||
|
fprintf(stderr, "Connection to server closed\n");
|
||||||
|
ustream_free(s);
|
||||||
|
close(con->fd.fd);
|
||||||
|
list_del(&con->list);
|
||||||
|
free(con);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void client_to_server_state(struct ustream *s) {
|
||||||
|
struct client *cl = container_of(s,
|
||||||
|
struct client, s.stream);
|
||||||
|
|
||||||
|
if (!s->eof)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fprintf(stderr, "eof!, pending: %d, total: %d\n", s->w.data_bytes, cl->ctr);
|
||||||
|
|
||||||
|
if (!s->w.data_bytes)
|
||||||
|
return client_to_server_close(s);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void client_read_cb(struct ustream *s, int bytes) {
|
||||||
|
char *str;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
do {
|
||||||
|
str = ustream_get_read_buf(s, &len);
|
||||||
|
if (!str)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (network_config.use_symm_enc) {
|
||||||
|
char *base64_dec_str = malloc(B64_DECODE_LEN(strlen(str)));
|
||||||
|
int base64_dec_length = b64_decode(str, base64_dec_str, B64_DECODE_LEN(strlen(str)));
|
||||||
|
char *dec = gcrypt_decrypt_msg(base64_dec_str, base64_dec_length);
|
||||||
|
|
||||||
|
free(base64_dec_str);
|
||||||
|
handle_network_msg(dec);
|
||||||
|
free(dec);
|
||||||
|
} else {
|
||||||
|
handle_network_msg(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
ustream_consume(s, len);
|
||||||
|
|
||||||
|
} while (1);
|
||||||
|
|
||||||
|
if (s->w.data_bytes > 256 && !ustream_read_blocked(s)) {
|
||||||
|
fprintf(stderr, "Block read, bytes: %d\n", s->w.data_bytes);
|
||||||
|
ustream_set_read_blocked(s, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void server_cb(struct uloop_fd *fd, unsigned int events) {
|
||||||
|
struct client *cl;
|
||||||
|
unsigned int sl = sizeof(struct sockaddr_in);
|
||||||
|
int sfd;
|
||||||
|
|
||||||
|
if (!next_client)
|
||||||
|
next_client = calloc(1, sizeof(*next_client));
|
||||||
|
|
||||||
|
cl = next_client;
|
||||||
|
sfd = accept(server.fd, (struct sockaddr *) &cl->sin, &sl);
|
||||||
|
if (sfd < 0) {
|
||||||
|
fprintf(stderr, "Accept failed\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cl->s.stream.string_data = 1;
|
||||||
|
cl->s.stream.notify_read = client_read_cb;
|
||||||
|
cl->s.stream.notify_state = client_notify_state;
|
||||||
|
cl->s.stream.notify_write = client_notify_write;
|
||||||
|
ustream_fd_init(&cl->s, sfd);
|
||||||
|
next_client = NULL;
|
||||||
|
fprintf(stderr, "New connection\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
int run_server(int port) {
|
||||||
|
char port_str[12];
|
||||||
|
sprintf(port_str, "%d", port);
|
||||||
|
|
||||||
|
server.cb = server_cb;
|
||||||
|
server.fd = usock(USOCK_TCP | USOCK_SERVER | USOCK_IPV4ONLY | USOCK_NUMERIC, INADDR_ANY, port_str);
|
||||||
|
if (server.fd < 0) {
|
||||||
|
perror("usock");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uloop_fd_add(&server, ULOOP_READ);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void client_not_be_used_read_cb(struct ustream *s, int bytes) {
|
||||||
|
int len;
|
||||||
|
char buf[2048];
|
||||||
|
|
||||||
|
len = ustream_read(s, buf, sizeof(buf));
|
||||||
|
buf[len] = '\0';
|
||||||
|
printf("Read %d bytes from SSL connection: %s\n", len, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void connect_cb(struct uloop_fd *f, unsigned int events) {
|
||||||
|
|
||||||
|
struct network_con_s *entry = container_of(f,
|
||||||
|
struct network_con_s, fd);
|
||||||
|
|
||||||
|
if (f->eof || f->error) {
|
||||||
|
fprintf(stderr, "Connection failed\n");
|
||||||
|
close(entry->fd.fd);
|
||||||
|
list_del(&entry->list);
|
||||||
|
free(entry);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "Connection established\n");
|
||||||
|
uloop_fd_delete(&entry->fd);
|
||||||
|
|
||||||
|
entry->stream.stream.notify_read = client_not_be_used_read_cb;
|
||||||
|
entry->stream.stream.notify_state = client_to_server_state;
|
||||||
|
|
||||||
|
ustream_fd_init(&entry->stream, entry->fd.fd);
|
||||||
|
entry->connected = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int add_tcp_conncection(char *ipv4, int port) {
|
||||||
|
struct sockaddr_in serv_addr;
|
||||||
|
|
||||||
|
char port_str[12];
|
||||||
|
sprintf(port_str, "%d", port);
|
||||||
|
|
||||||
|
memset(&serv_addr, 0, sizeof(serv_addr));
|
||||||
|
serv_addr.sin_family = AF_INET;
|
||||||
|
serv_addr.sin_addr.s_addr = inet_addr(ipv4);
|
||||||
|
serv_addr.sin_port = htons(port);
|
||||||
|
|
||||||
|
struct network_con_s *tmp = tcp_list_contains_address(serv_addr);
|
||||||
|
if (tmp != NULL) {
|
||||||
|
if(tmp->connected == true)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
} else{
|
||||||
|
// Delete already existing entry
|
||||||
|
close(tmp->fd.fd);
|
||||||
|
list_del(&tmp->list);
|
||||||
|
free(tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct network_con_s *tcp_entry = calloc(1, sizeof(struct network_con_s));
|
||||||
|
tcp_entry->fd.fd = usock(USOCK_TCP | USOCK_NONBLOCK, ipv4, port_str);
|
||||||
|
tcp_entry->sock_addr = serv_addr;
|
||||||
|
|
||||||
|
if (tcp_entry->fd.fd < 0) {
|
||||||
|
free(tcp_entry);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
tcp_entry->fd.cb = connect_cb;
|
||||||
|
uloop_fd_add(&tcp_entry->fd, ULOOP_WRITE | ULOOP_EDGE_TRIGGER);
|
||||||
|
|
||||||
|
printf("New TCP connection to %s:%d\n", ipv4, port);
|
||||||
|
list_add(&tcp_entry->list, &tcp_sock_list);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void send_tcp(char *msg) {
|
||||||
|
print_tcp_array();
|
||||||
|
if (network_config.use_symm_enc) {
|
||||||
|
int length_enc;
|
||||||
|
size_t msglen = strlen(msg);
|
||||||
|
char *enc = gcrypt_encrypt_msg(msg, msglen + 1, &length_enc);
|
||||||
|
|
||||||
|
char *base64_enc_str = malloc(B64_ENCODE_LEN(length_enc));
|
||||||
|
size_t base64_enc_length = b64_encode(enc, length_enc, base64_enc_str, B64_ENCODE_LEN(length_enc));
|
||||||
|
struct network_con_s *con;
|
||||||
|
list_for_each_entry(con, &tcp_sock_list, list)
|
||||||
|
{
|
||||||
|
if (con->connected) {
|
||||||
|
int len_ustream = ustream_write(&con->stream.stream, base64_enc_str, base64_enc_length, 0);
|
||||||
|
printf("Ustream send: %d\n", len_ustream);
|
||||||
|
if (len_ustream <= 0) {
|
||||||
|
fprintf(stderr,"Ustream error!\n");
|
||||||
|
//TODO: ERROR HANDLING!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
free(base64_enc_str);
|
||||||
|
free(enc);
|
||||||
|
} else {
|
||||||
|
struct network_con_s *con;
|
||||||
|
|
||||||
|
list_for_each_entry(con, &tcp_sock_list, list)
|
||||||
|
{
|
||||||
|
if (con->connected) {
|
||||||
|
if (ustream_printf(&con->stream.stream, "%s", msg) == 0) {
|
||||||
|
//TODO: ERROR HANDLING!
|
||||||
|
fprintf(stderr,"Ustream error!\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct network_con_s* tcp_list_contains_address(struct sockaddr_in entry) {
|
||||||
|
struct network_con_s *con;
|
||||||
|
|
||||||
|
list_for_each_entry(con, &tcp_sock_list, list)
|
||||||
|
{
|
||||||
|
if(entry.sin_addr.s_addr == con->sock_addr.sin_addr.s_addr)
|
||||||
|
{
|
||||||
|
return con;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_tcp_array() {
|
||||||
|
struct network_con_s *con;
|
||||||
|
|
||||||
|
printf("--------Connections------\n");
|
||||||
|
list_for_each_entry(con, &tcp_sock_list, list)
|
||||||
|
{
|
||||||
|
printf("Conenctin to Port: %d, Connected: %s\n", con->sock_addr.sin_port, con->connected ? "True" : "False");
|
||||||
|
}
|
||||||
|
printf("------------------\n");
|
||||||
|
}
|
1290
src/storage/datastorage.c
Normal file
1290
src/storage/datastorage.c
Normal file
File diff suppressed because it is too large
Load diff
356
src/utils/dawn_iwinfo.c
Normal file
356
src/utils/dawn_iwinfo.c
Normal file
|
@ -0,0 +1,356 @@
|
||||||
|
#include "dawn_iwinfo.h"
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
#include <iwinfo.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
|
||||||
|
#include "utils.h"
|
||||||
|
#include "ubus.h"
|
||||||
|
|
||||||
|
#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
|
||||||
|
|
||||||
|
int call_iwinfo(char *client_addr);
|
||||||
|
|
||||||
|
int parse_rssi(char *iwinfo_string);
|
||||||
|
|
||||||
|
int get_rssi(const char *ifname, uint8_t *client_addr);
|
||||||
|
|
||||||
|
int get_bandwidth(const char *ifname, uint8_t *client_addr, float *rx_rate, float *tx_rate);
|
||||||
|
|
||||||
|
#define IWINFO_BUFSIZE 24 * 1024
|
||||||
|
|
||||||
|
#define IWINFO_ESSID_MAX_SIZE 32
|
||||||
|
|
||||||
|
int compare_essid_iwinfo(__uint8_t *bssid_addr, __uint8_t *bssid_addr_to_compare) {
|
||||||
|
const struct iwinfo_ops *iw;
|
||||||
|
|
||||||
|
char mac_buf[20];
|
||||||
|
char mac_buf_to_compare[20];
|
||||||
|
sprintf(mac_buf, MACSTR, MAC2STR(bssid_addr));
|
||||||
|
sprintf(mac_buf_to_compare, MACSTR, MAC2STR(bssid_addr_to_compare));
|
||||||
|
|
||||||
|
DIR *dirp;
|
||||||
|
struct dirent *entry;
|
||||||
|
dirp = opendir(hostapd_dir_glob); // error handling?
|
||||||
|
if (!dirp) {
|
||||||
|
fprintf(stderr, "[COMPARE ESSID] Failed to open %s\n", hostapd_dir_glob);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *essid = NULL;
|
||||||
|
char *essid_to_compare = NULL;
|
||||||
|
|
||||||
|
char buf_essid[IWINFO_ESSID_MAX_SIZE + 1] = {0};
|
||||||
|
char buf_essid_to_compare[IWINFO_ESSID_MAX_SIZE + 1] = {0};
|
||||||
|
|
||||||
|
while ((entry = readdir(dirp)) != NULL && (essid == NULL || essid_to_compare == NULL)) {
|
||||||
|
if (entry->d_type == DT_SOCK) {
|
||||||
|
|
||||||
|
iw = iwinfo_backend(entry->d_name);
|
||||||
|
|
||||||
|
static char buf_bssid[18] = {0};
|
||||||
|
if (iw->bssid(entry->d_name, buf_bssid))
|
||||||
|
snprintf(buf_bssid, sizeof(buf_bssid), "00:00:00:00:00:00");
|
||||||
|
|
||||||
|
if (strcmp(mac_buf, buf_bssid) == 0) {
|
||||||
|
|
||||||
|
if (iw->ssid(entry->d_name, buf_essid))
|
||||||
|
memset(buf_essid, 0, sizeof(buf_essid));
|
||||||
|
essid = buf_essid;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(mac_buf_to_compare, buf_bssid) == 0) {
|
||||||
|
if (iw->ssid(entry->d_name, buf_essid_to_compare))
|
||||||
|
memset(buf_essid_to_compare, 0, sizeof(buf_essid_to_compare));
|
||||||
|
essid_to_compare = buf_essid_to_compare;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
closedir(dirp);
|
||||||
|
|
||||||
|
printf("Comparing: %s with %s\n", essid, essid_to_compare);
|
||||||
|
|
||||||
|
if (essid == NULL || essid_to_compare == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(essid, essid_to_compare) == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_bandwidth_iwinfo(__uint8_t *client_addr, float *rx_rate, float *tx_rate) {
|
||||||
|
|
||||||
|
DIR *dirp;
|
||||||
|
struct dirent *entry;
|
||||||
|
dirp = opendir(hostapd_dir_glob); // error handling?
|
||||||
|
if (!dirp) {
|
||||||
|
fprintf(stderr, "[BANDWITH INFO] Failed to open %s\n", hostapd_dir_glob);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sucess = 0;
|
||||||
|
|
||||||
|
while ((entry = readdir(dirp)) != NULL) {
|
||||||
|
if (entry->d_type == DT_SOCK) {
|
||||||
|
if (get_bandwidth(entry->d_name, client_addr, rx_rate, tx_rate)) {
|
||||||
|
sucess = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
closedir(dirp);
|
||||||
|
return sucess;
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_bandwidth(const char *ifname, uint8_t *client_addr, float *rx_rate, float *tx_rate) {
|
||||||
|
|
||||||
|
int i, len;
|
||||||
|
char buf[IWINFO_BUFSIZE];
|
||||||
|
struct iwinfo_assoclist_entry *e;
|
||||||
|
const struct iwinfo_ops *iw;
|
||||||
|
|
||||||
|
iw = iwinfo_backend(ifname);
|
||||||
|
|
||||||
|
if (iw->assoclist(ifname, buf, &len)) {
|
||||||
|
fprintf(stderr, "No information available\n");
|
||||||
|
iwinfo_finish();
|
||||||
|
return 0;
|
||||||
|
} else if (len <= 0) {
|
||||||
|
fprintf(stderr, "No station connected\n");
|
||||||
|
iwinfo_finish();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < len; i += sizeof(struct iwinfo_assoclist_entry)) {
|
||||||
|
e = (struct iwinfo_assoclist_entry *) &buf[i];
|
||||||
|
|
||||||
|
if (mac_is_equal(client_addr, e->mac)) {
|
||||||
|
*rx_rate = e->rx_rate.rate / 1000;
|
||||||
|
*tx_rate = e->tx_rate.rate / 1000;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_rssi_iwinfo(__uint8_t *client_addr) {
|
||||||
|
|
||||||
|
DIR *dirp;
|
||||||
|
struct dirent *entry;
|
||||||
|
dirp = opendir(hostapd_dir_glob); // error handling?
|
||||||
|
if (!dirp) {
|
||||||
|
fprintf(stderr, "[RSSI INFO] No hostapd sockets!\n");
|
||||||
|
return INT_MIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rssi = INT_MIN;
|
||||||
|
|
||||||
|
while ((entry = readdir(dirp)) != NULL) {
|
||||||
|
if (entry->d_type == DT_SOCK) {
|
||||||
|
rssi = get_rssi(entry->d_name, client_addr);
|
||||||
|
if (rssi != INT_MIN)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
closedir(dirp);
|
||||||
|
return rssi;
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_rssi(const char *ifname, uint8_t *client_addr) {
|
||||||
|
|
||||||
|
int i, len;
|
||||||
|
char buf[IWINFO_BUFSIZE];
|
||||||
|
struct iwinfo_assoclist_entry *e;
|
||||||
|
const struct iwinfo_ops *iw;
|
||||||
|
|
||||||
|
iw = iwinfo_backend(ifname);
|
||||||
|
|
||||||
|
if (iw->assoclist(ifname, buf, &len)) {
|
||||||
|
fprintf(stderr, "No information available\n");
|
||||||
|
iwinfo_finish();
|
||||||
|
return INT_MIN;
|
||||||
|
} else if (len <= 0) {
|
||||||
|
fprintf(stderr, "No station connected\n");
|
||||||
|
iwinfo_finish();
|
||||||
|
return INT_MIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < len; i += sizeof(struct iwinfo_assoclist_entry)) {
|
||||||
|
e = (struct iwinfo_assoclist_entry *) &buf[i];
|
||||||
|
|
||||||
|
if (mac_is_equal(client_addr, e->mac))
|
||||||
|
return e->signal;
|
||||||
|
}
|
||||||
|
|
||||||
|
iwinfo_finish();
|
||||||
|
return INT_MIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_expected_throughput_iwinfo(__uint8_t *client_addr) {
|
||||||
|
|
||||||
|
DIR *dirp;
|
||||||
|
struct dirent *entry;
|
||||||
|
dirp = opendir(hostapd_dir_glob); // error handling?
|
||||||
|
if (!dirp) {
|
||||||
|
fprintf(stderr, "[RSSI INFO] Failed to open dir:%s\n", hostapd_dir_glob);
|
||||||
|
return INT_MIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
int exp_thr = INT_MIN;
|
||||||
|
|
||||||
|
while ((entry = readdir(dirp)) != NULL) {
|
||||||
|
if (entry->d_type == DT_SOCK) {
|
||||||
|
exp_thr = get_expected_throughput(entry->d_name, client_addr);
|
||||||
|
if (exp_thr != INT_MIN)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
closedir(dirp);
|
||||||
|
return exp_thr;
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_expected_throughput(const char *ifname, uint8_t *client_addr) {
|
||||||
|
|
||||||
|
int i, len;
|
||||||
|
char buf[IWINFO_BUFSIZE];
|
||||||
|
struct iwinfo_assoclist_entry *e;
|
||||||
|
const struct iwinfo_ops *iw;
|
||||||
|
|
||||||
|
iw = iwinfo_backend(ifname);
|
||||||
|
|
||||||
|
if (iw->assoclist(ifname, buf, &len)) {
|
||||||
|
fprintf(stderr, "No information available\n");
|
||||||
|
return INT_MIN;
|
||||||
|
} else if (len <= 0) {
|
||||||
|
fprintf(stderr, "No station connected\n");
|
||||||
|
return INT_MIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < len; i += sizeof(struct iwinfo_assoclist_entry)) {
|
||||||
|
e = (struct iwinfo_assoclist_entry *) &buf[i];
|
||||||
|
|
||||||
|
if (mac_is_equal(client_addr, e->mac))
|
||||||
|
return e->thr;
|
||||||
|
}
|
||||||
|
iwinfo_finish();
|
||||||
|
|
||||||
|
return INT_MIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_bssid(const char *ifname, uint8_t *bssid_addr) {
|
||||||
|
const struct iwinfo_ops *iw;
|
||||||
|
|
||||||
|
iw = iwinfo_backend(ifname);
|
||||||
|
|
||||||
|
static char buf[18] = { 0 };
|
||||||
|
|
||||||
|
if (iw->bssid(ifname, buf))
|
||||||
|
snprintf(buf, sizeof(buf), "00:00:00:00:00:00");
|
||||||
|
|
||||||
|
hwaddr_aton(buf,bssid_addr);
|
||||||
|
iwinfo_finish();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_ssid(const char *ifname, char* ssid) {
|
||||||
|
const struct iwinfo_ops *iw;
|
||||||
|
char buf[IWINFO_ESSID_MAX_SIZE+1] = { 0 };
|
||||||
|
|
||||||
|
iw = iwinfo_backend(ifname);
|
||||||
|
if (iw->ssid(ifname, buf))
|
||||||
|
memset(buf, 0, sizeof(buf));
|
||||||
|
|
||||||
|
memcpy(ssid, buf, (SSID_MAX_LEN) * sizeof(char));
|
||||||
|
strcpy(ssid, buf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_channel_utilization(const char *ifname, uint64_t *last_channel_time, uint64_t *last_channel_time_busy) {
|
||||||
|
|
||||||
|
int len;
|
||||||
|
const struct iwinfo_ops *iw;
|
||||||
|
char buf[IWINFO_BUFSIZE];
|
||||||
|
struct iwinfo_survey_entry *e;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
iw = iwinfo_backend(ifname);
|
||||||
|
|
||||||
|
int freq;
|
||||||
|
if (iw->frequency(ifname, &freq))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iw->survey(ifname, buf, &len))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Survey not possible!\n\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if (len <= 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "No survey results\n\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0, x = 1; i < len; i += sizeof(struct iwinfo_survey_entry), x++)
|
||||||
|
{
|
||||||
|
e = (struct iwinfo_survey_entry *) &buf[i];
|
||||||
|
|
||||||
|
if(e->mhz == freq)
|
||||||
|
{
|
||||||
|
uint64_t dividend = e->busy_time - *last_channel_time_busy;
|
||||||
|
uint64_t divisor = e->active_time - *last_channel_time;
|
||||||
|
*last_channel_time = e->active_time;
|
||||||
|
*last_channel_time_busy = e->busy_time;
|
||||||
|
|
||||||
|
if(divisor)
|
||||||
|
ret = (int)(dividend * 255 / divisor);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
iwinfo_finish();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int support_ht(const char *ifname) {
|
||||||
|
const struct iwinfo_ops *iw;
|
||||||
|
|
||||||
|
iw = iwinfo_backend(ifname);
|
||||||
|
int htmodes = 0;
|
||||||
|
|
||||||
|
if (iw->htmodelist(ifname, &htmodes))
|
||||||
|
{
|
||||||
|
printf("No HT mode information available\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t ht_support_bitmask = (1 << 0) | (1 << 2);
|
||||||
|
int ret = htmodes & ht_support_bitmask ? 1 : 0;
|
||||||
|
iwinfo_finish();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int support_vht(const char *ifname) {
|
||||||
|
const struct iwinfo_ops *iw;
|
||||||
|
|
||||||
|
iw = iwinfo_backend(ifname);
|
||||||
|
int htmodes = 0;
|
||||||
|
|
||||||
|
if (iw->htmodelist(ifname, &htmodes))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "No VHT mode information available\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t vht_support_bitmask = (1 << 2) | (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6);
|
||||||
|
int ret = htmodes & vht_support_bitmask ? 1 : 0;
|
||||||
|
iwinfo_finish();
|
||||||
|
return ret;
|
||||||
|
}
|
202
src/utils/dawn_uci.c
Normal file
202
src/utils/dawn_uci.c
Normal file
|
@ -0,0 +1,202 @@
|
||||||
|
#include <uci.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <datastorage.h>
|
||||||
|
|
||||||
|
#include "dawn_uci.h"
|
||||||
|
|
||||||
|
|
||||||
|
static struct uci_context *uci_ctx;
|
||||||
|
static struct uci_package *uci_pkg;
|
||||||
|
|
||||||
|
// why is this not included in uci lib...?!
|
||||||
|
// found here: https://github.com/br101/pingcheck/blob/master/uci.c
|
||||||
|
static int uci_lookup_option_int(struct uci_context *uci, struct uci_section *s,
|
||||||
|
const char *name) {
|
||||||
|
const char *str = uci_lookup_option_string(uci, s, name);
|
||||||
|
return str == NULL ? -1 : atoi(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct time_config_s uci_get_time_config() {
|
||||||
|
struct time_config_s ret;
|
||||||
|
|
||||||
|
struct uci_element *e;
|
||||||
|
uci_foreach_element(&uci_pkg->sections, e)
|
||||||
|
{
|
||||||
|
struct uci_section *s = uci_to_section(e);
|
||||||
|
|
||||||
|
if (strcmp(s->type, "times") == 0) {
|
||||||
|
ret.update_client = uci_lookup_option_int(uci_ctx, s, "update_client");
|
||||||
|
ret.remove_client = uci_lookup_option_int(uci_ctx, s, "remove_client");
|
||||||
|
ret.remove_probe = uci_lookup_option_int(uci_ctx, s, "remove_probe");
|
||||||
|
ret.update_hostapd = uci_lookup_option_int(uci_ctx, s, "update_hostapd");
|
||||||
|
ret.remove_ap = uci_lookup_option_int(uci_ctx, s, "remove_ap");
|
||||||
|
ret.update_tcp_con = uci_lookup_option_int(uci_ctx, s, "update_tcp_con");
|
||||||
|
ret.denied_req_threshold = uci_lookup_option_int(uci_ctx, s, "denied_req_threshold");
|
||||||
|
ret.update_chan_util = uci_lookup_option_int(uci_ctx, s, "update_chan_util");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct probe_metric_s uci_get_dawn_metric() {
|
||||||
|
struct probe_metric_s ret;
|
||||||
|
|
||||||
|
struct uci_element *e;
|
||||||
|
uci_foreach_element(&uci_pkg->sections, e)
|
||||||
|
{
|
||||||
|
struct uci_section *s = uci_to_section(e);
|
||||||
|
|
||||||
|
if (strcmp(s->type, "metric") == 0) {
|
||||||
|
ret.ap_weight = uci_lookup_option_int(uci_ctx, s, "ap_weight");
|
||||||
|
ret.kicking = uci_lookup_option_int(uci_ctx, s, "kicking");
|
||||||
|
ret.ht_support = uci_lookup_option_int(uci_ctx, s, "ht_support");
|
||||||
|
ret.vht_support = uci_lookup_option_int(uci_ctx, s, "vht_support");
|
||||||
|
ret.no_ht_support = uci_lookup_option_int(uci_ctx, s, "no_ht_support");
|
||||||
|
ret.no_vht_support = uci_lookup_option_int(uci_ctx, s, "no_vht_support");
|
||||||
|
ret.rssi = uci_lookup_option_int(uci_ctx, s, "rssi");
|
||||||
|
ret.freq = uci_lookup_option_int(uci_ctx, s, "freq");
|
||||||
|
ret.rssi_val = uci_lookup_option_int(uci_ctx, s, "rssi_val");
|
||||||
|
ret.chan_util = uci_lookup_option_int(uci_ctx, s, "chan_util");
|
||||||
|
ret.max_chan_util = uci_lookup_option_int(uci_ctx, s, "max_chan_util");
|
||||||
|
ret.chan_util_val = uci_lookup_option_int(uci_ctx, s, "chan_util_val");
|
||||||
|
ret.max_chan_util_val = uci_lookup_option_int(uci_ctx, s, "max_chan_util_val");
|
||||||
|
ret.min_probe_count = uci_lookup_option_int(uci_ctx, s, "min_probe_count");
|
||||||
|
ret.low_rssi = uci_lookup_option_int(uci_ctx, s, "low_rssi");
|
||||||
|
ret.low_rssi_val = uci_lookup_option_int(uci_ctx, s, "low_rssi_val");
|
||||||
|
ret.bandwith_threshold = uci_lookup_option_int(uci_ctx, s, "bandwith_threshold");
|
||||||
|
ret.use_station_count = uci_lookup_option_int(uci_ctx, s, "use_station_count");
|
||||||
|
ret.eval_probe_req = uci_lookup_option_int(uci_ctx, s, "eval_probe_req");
|
||||||
|
ret.eval_auth_req = uci_lookup_option_int(uci_ctx, s, "eval_auth_req");
|
||||||
|
ret.eval_assoc_req = uci_lookup_option_int(uci_ctx, s, "eval_assoc_req");
|
||||||
|
ret.deny_auth_reason = uci_lookup_option_int(uci_ctx, s, "deny_auth_reason");
|
||||||
|
ret.deny_assoc_reason = uci_lookup_option_int(uci_ctx, s, "deny_assoc_reason");
|
||||||
|
ret.max_station_diff = uci_lookup_option_int(uci_ctx, s, "max_station_diff");
|
||||||
|
ret.use_driver_recog = uci_lookup_option_int(uci_ctx, s, "use_driver_recog");
|
||||||
|
ret.min_kick_count = uci_lookup_option_int(uci_ctx, s, "min_number_to_kick");
|
||||||
|
ret.chan_util_avg_period = uci_lookup_option_int(uci_ctx, s, "chan_util_avg_period");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct network_config_s uci_get_dawn_network() {
|
||||||
|
struct network_config_s ret;
|
||||||
|
|
||||||
|
struct uci_element *e;
|
||||||
|
uci_foreach_element(&uci_pkg->sections, e)
|
||||||
|
{
|
||||||
|
struct uci_section *s = uci_to_section(e);
|
||||||
|
|
||||||
|
if (strcmp(s->type, "network") == 0) {
|
||||||
|
ret.broadcast_ip = uci_lookup_option_string(uci_ctx, s, "broadcast_ip");
|
||||||
|
ret.broadcast_port = uci_lookup_option_int(uci_ctx, s, "broadcast_port");
|
||||||
|
ret.bool_multicast = uci_lookup_option_int(uci_ctx, s, "multicast");
|
||||||
|
ret.shared_key = uci_lookup_option_string(uci_ctx, s, "shared_key");
|
||||||
|
ret.iv = uci_lookup_option_string(uci_ctx, s, "iv");
|
||||||
|
ret.network_option = uci_lookup_option_int(uci_ctx, s, "network_option");
|
||||||
|
ret.tcp_port = uci_lookup_option_int(uci_ctx, s, "tcp_port");
|
||||||
|
ret.use_symm_enc = uci_lookup_option_int(uci_ctx, s, "use_symm_enc");
|
||||||
|
ret.collision_domain = uci_lookup_option_int(uci_ctx, s, "collision_domain");
|
||||||
|
ret.bandwidth = uci_lookup_option_int(uci_ctx, s, "bandwidth");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *uci_get_dawn_hostapd_dir() {
|
||||||
|
struct uci_element *e;
|
||||||
|
uci_foreach_element(&uci_pkg->sections, e)
|
||||||
|
{
|
||||||
|
struct uci_section *s = uci_to_section(e);
|
||||||
|
|
||||||
|
if (strcmp(s->type, "hostapd") == 0) {
|
||||||
|
return uci_lookup_option_string(uci_ctx, s, "hostapd_dir");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *uci_get_dawn_sort_order() {
|
||||||
|
struct uci_element *e;
|
||||||
|
uci_foreach_element(&uci_pkg->sections, e)
|
||||||
|
{
|
||||||
|
struct uci_section *s = uci_to_section(e);
|
||||||
|
|
||||||
|
if (strcmp(s->type, "ordering") == 0) {
|
||||||
|
return uci_lookup_option_string(uci_ctx, s, "sort_order");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int uci_reset()
|
||||||
|
{
|
||||||
|
uci_unload(uci_ctx, uci_pkg);
|
||||||
|
uci_load(uci_ctx, "dawn", &uci_pkg);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int uci_init() {
|
||||||
|
struct uci_context *ctx = uci_ctx;
|
||||||
|
|
||||||
|
if (!ctx) {
|
||||||
|
ctx = uci_alloc_context();
|
||||||
|
uci_ctx = ctx;
|
||||||
|
|
||||||
|
ctx->flags &= ~UCI_FLAG_STRICT;
|
||||||
|
} else {
|
||||||
|
// shouldn't happen?
|
||||||
|
uci_pkg = uci_lookup_package(ctx, "dawn");
|
||||||
|
if (uci_pkg)
|
||||||
|
uci_unload(ctx, uci_pkg);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uci_load(ctx, "dawn", &uci_pkg))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int uci_clear() {
|
||||||
|
if (uci_pkg != NULL) {
|
||||||
|
uci_unload(uci_ctx, uci_pkg);
|
||||||
|
}
|
||||||
|
if (uci_ctx != NULL) {
|
||||||
|
uci_free_context(uci_ctx);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int uci_set_network(char* uci_cmd)
|
||||||
|
{
|
||||||
|
struct uci_ptr ptr;
|
||||||
|
int ret = UCI_OK;
|
||||||
|
struct uci_context *ctx;
|
||||||
|
|
||||||
|
ctx = uci_alloc_context();
|
||||||
|
ctx->flags |= UCI_FLAG_STRICT;
|
||||||
|
|
||||||
|
if (uci_lookup_ptr(ctx, &ptr, uci_cmd, 1) != UCI_OK) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = uci_set(ctx, &ptr);
|
||||||
|
|
||||||
|
|
||||||
|
if (uci_lookup_ptr(ctx, &ptr, "dawn", 1) != UCI_OK) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uci_commit(ctx, &ptr.p, 0) != UCI_OK) {
|
||||||
|
fprintf(stderr, "Failed to commit UCI cmd: %s\n", uci_cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
11
src/utils/ieee80211_utils.c
Normal file
11
src/utils/ieee80211_utils.c
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#include "ieee80211_utils.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
double iee80211_calculate_bitrate(uint8_t supp_rate_val) {
|
||||||
|
return ((double) supp_rate_val) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
double iee80211_calculate_expected_throughput_mbit(int exp_thr) {
|
||||||
|
return (((double) exp_thr) / 1000);
|
||||||
|
}
|
1619
src/utils/ubus.c
Normal file
1619
src/utils/ubus.c
Normal file
File diff suppressed because it is too large
Load diff
80
src/utils/utils.c
Normal file
80
src/utils/utils.c
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
#include "utils.h"
|
||||||
|
#include "ubus.h"
|
||||||
|
|
||||||
|
int string_is_greater(uint8_t *str, uint8_t *str_2) {
|
||||||
|
|
||||||
|
int length_1 = strlen((char *) str);
|
||||||
|
int length_2 = strlen((char *) str_2);
|
||||||
|
|
||||||
|
int length = length_1 < length_2 ? length_1 : length_2;
|
||||||
|
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
if (str[i] > str_2[i]) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (str[i] < str_2[i]) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return length_1 > length_2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// source: https://elixir.bootlin.com/linux/v4.9/source/lib/hexdump.c#L28
|
||||||
|
int hex_to_bin(char ch) {
|
||||||
|
if ((ch >= '0') && (ch <= '9')) return ch - '0';
|
||||||
|
ch = tolower(ch);
|
||||||
|
if ((ch >= 'a') && (ch <= 'f')) return ch - 'a' + 10;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// based on: hostapd src/utils/common.c
|
||||||
|
int hwaddr_aton(const char *txt, uint8_t *addr) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < ETH_ALEN; i++) {
|
||||||
|
int a, b;
|
||||||
|
|
||||||
|
a = hex_to_bin(*txt++);
|
||||||
|
if (a < 0) return -1;
|
||||||
|
b = hex_to_bin(*txt++);
|
||||||
|
if (b < 0) return -1;
|
||||||
|
*addr++ = (a << 4) | b;
|
||||||
|
if (i < 5 && *txt++ != ':') return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int convert_mac(char *in, char *out) {
|
||||||
|
int i, j = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < 6; i++) {
|
||||||
|
if (in[j + 1] != ':' && in[j + 1] != '\0') {
|
||||||
|
out[3 * i] = toupper(in[j]);
|
||||||
|
out[(3 * i) + 1] = toupper(in[j + 1]);
|
||||||
|
out[(3 * i) + 2] = in[j + 2];
|
||||||
|
j += 3;
|
||||||
|
} else {
|
||||||
|
out[3 * i] = '0';
|
||||||
|
out[(3 * i) + 1] = toupper(in[j]);
|
||||||
|
out[(3 * i) + 2] = toupper(in[j + 1]);
|
||||||
|
j += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_mac_to_file(char *path, uint8_t addr[]) {
|
||||||
|
FILE *f = fopen(path, "a");
|
||||||
|
if (f == NULL) {
|
||||||
|
fprintf(stderr,"Error opening mac file!\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
char mac_buf[20];
|
||||||
|
sprintf(mac_buf, MACSTR, MAC2STR(addr));
|
||||||
|
|
||||||
|
fprintf(f, "%s\n", mac_buf);
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
}
|
Loading…
Reference in a new issue