mirror of
https://git.busybox.net/udhcp
synced 2025-10-14 01:59:23 +08:00
Initial revision
This commit is contained in:
13
AUTHORS
Normal file
13
AUTHORS
Normal file
@@ -0,0 +1,13 @@
|
||||
NETtel DHCP Server Authors
|
||||
--------------------------
|
||||
|
||||
Matthew Ramsay <matthewr@moreton.com.au> (Moreton Bay)
|
||||
Chris Trew <christ@moreton.com.au> (Moreton Bay)
|
||||
|
||||
|
||||
|
||||
Other Credits:
|
||||
--------------
|
||||
Moreton Bay (http://www.moretonbay.com/)
|
||||
|
||||
|
339
COPYING
Normal file
339
COPYING
Normal file
@@ -0,0 +1,339 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
675 Mass Ave, Cambridge, MA 02139, 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 Library 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
|
||||
|
||||
Appendix: 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.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) 19yy <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) 19yy name of author
|
||||
Gnomovision 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 Library General
|
||||
Public License instead of this License.
|
132
ChangeLog
Normal file
132
ChangeLog
Normal file
@@ -0,0 +1,132 @@
|
||||
0.8.29 (000323)
|
||||
+ stable(?) release
|
||||
|
||||
0.8.28 (000323)
|
||||
+ removed alarm as it was causing server to go down
|
||||
+ removed debugging
|
||||
+ break down dhcpd.c into manageable files
|
||||
|
||||
|
||||
0.8.27 (000221)
|
||||
+ OFFER also sends gateway/subnet (for picky dhcp clients)
|
||||
+ multiple DNS now handled from resolv.conf if available
|
||||
+ multiple WINS (from dhcpd.conf)
|
||||
|
||||
0.8.25 (000120)
|
||||
+ now compiles *and* runs on a generic linux system
|
||||
tested with a windows 98 client and the sample config
|
||||
files in the samples directory.
|
||||
|
||||
0.8.24 (000117)
|
||||
+ makeiplist tool has basic functionality in place
|
||||
+ new sample config files
|
||||
+ route add -host 255.255.255.255 dev eth0 added for generic linux
|
||||
|
||||
0.8.23 (000117)
|
||||
+ NETtel specific fix for ignoring dhcp requests on 2nd interface
|
||||
|
||||
0.8.22 (000113)
|
||||
+ minor changes to compile under a generic linux system
|
||||
+ minor config file location changes for a generic linux system
|
||||
+ makeiplist fixes.. still incomplete.. but etting closer
|
||||
|
||||
0.8.21 (000113)
|
||||
+ now sends the correct server ip instead of hardcoded value
|
||||
+ minor debugging fixes for critical messages
|
||||
|
||||
0.8.20 (000106)
|
||||
+ cut out dhcp server checking.. this was causing dialout ppp
|
||||
sessions with idle time set to never time out.
|
||||
+ also removed the 10 second pause before launching.. as this
|
||||
was originally to stop it replying to a dhcp client
|
||||
on a NETtel which was really a bad way to do it in the
|
||||
first place :-)
|
||||
|
||||
0.8.19 (000104)
|
||||
+ fixes for route add -host on a machine that needs to run both
|
||||
a DHCP client and server (dual eth box)
|
||||
|
||||
0.8.18 (991220)
|
||||
|
||||
+ Race conditions fixed by disabling alarm whilst the server is busy
|
||||
+ Fixed continous clearing of the offered array so that it is only cleared
|
||||
when it is dirty - (could change the position of when dirty is set)
|
||||
|
||||
0.8.17 (991212)
|
||||
|
||||
- has problems clearing out the offered array
|
||||
|
||||
0.8.16 (991203)
|
||||
+ Non blocking error is changes to informational as it is not really
|
||||
an error
|
||||
|
||||
0.8.15 (991129)
|
||||
+ Servs the dns field 3 times (Nettel only) so that windows servers
|
||||
dont time out whilst nettel is booting
|
||||
|
||||
0.8.14 (991126)
|
||||
+ added owner check for the offered array so clean out time may be
|
||||
increased
|
||||
+ added new func to print out chadder/MAC
|
||||
|
||||
0.8.13 (991125)
|
||||
+ added win95 support (w95 changed xid halfway through conversation)
|
||||
+ had to change the offered array to use hardware addresses instead of xid
|
||||
+ fixed re offered bug
|
||||
+ added more debugging
|
||||
|
||||
0.8.12 (991111)
|
||||
+ debugging was real bad.. cleaned up a bit.. needs overhaul
|
||||
|
||||
|
||||
0.8.11 (991110)
|
||||
+ fixed up offeredAddr array to actually be used now!! offeredAddr is
|
||||
used to see if another simultaneous connecting client was offered
|
||||
an address that we are about to offer another client (multiple
|
||||
client bug)
|
||||
+ removed re_offered variable as it breaks multiple client support
|
||||
+ added lease time to ACK -- doesn't work if in OFFER
|
||||
+ decreased internal array clear delay to 60 seconds
|
||||
+ minor findAddr bug (returning -1 instead of 0)
|
||||
+ if clients xid already in offeredAddr offer the same addr and don't add a
|
||||
new addr to offered (caused by a client issuing multiple DISCOVERs)
|
||||
|
||||
0.8.10 (991105)
|
||||
+ \n bug in arpping
|
||||
+ minor debugging changes (removed printfs etc)
|
||||
+ started browseiplist (not finished)
|
||||
|
||||
0.8.9 (19991105)
|
||||
+ fixed options array size bug (options were cut off)
|
||||
|
||||
0.8.8 (19991105)
|
||||
+ ignores requests from dhcpcd on the same machine
|
||||
|
||||
0.8.7 (19991104)
|
||||
+ don't die if we can't bind to search for existing DHCP server
|
||||
+ slightly more verbose syslogging
|
||||
|
||||
0.8.6 (19991103)
|
||||
+ added makeiplist (not finished -- core dumps)
|
||||
+ minor debug changes
|
||||
|
||||
0.8.5 (19991029)
|
||||
+ exits if another DHCP server is already on the network
|
||||
+ added Linux Makefile
|
||||
|
||||
0.8.4 (19991026)
|
||||
+ minor bug fix in findaddr preventing an addr being found
|
||||
|
||||
0.8.3 (19991025)
|
||||
+ fixed up debugging
|
||||
+ minor hwaddr issues
|
||||
|
||||
0.8.2 (19991022)
|
||||
+ free leases (new arpping code from dhcpcd)
|
||||
+ fixed bug where crashes if no leases/iplist file
|
||||
+ syslogging and debugging switch
|
||||
+ serve DNS from resolv.conf
|
||||
+ fixed bug where new lease added if same mac offered
|
||||
+ now checks the ip is free b4 offering
|
||||
+ now supports wins server
|
||||
|
22
Makefile
Normal file
22
Makefile
Normal file
@@ -0,0 +1,22 @@
|
||||
|
||||
EXEC = dhcpd
|
||||
OBJS = dhcpd.o arpping.o socket.o options.o files.o debug.o nettel.o
|
||||
|
||||
ifdef BUILD_NETtel
|
||||
CFLAGS += -DCONFIG_NETtel
|
||||
endif
|
||||
ifdef BUILD_NETtel1500
|
||||
CFLAGS += -DCONFIG_NETtel
|
||||
endif
|
||||
|
||||
all: $(EXEC)
|
||||
|
||||
$(EXEC): $(OBJS)
|
||||
$(LD) $(LDFLAGS) -o $@.elf $(OBJS) $(LDLIBS)
|
||||
$(CONVERT)
|
||||
|
||||
clean:
|
||||
-rm -f $(EXEC) *.elf *.gdb *.o
|
||||
|
||||
$(OBJS): dhcpd.h socket.h options.h files.h debug.h nettel.h
|
||||
|
31
Makefile.linux
Normal file
31
Makefile.linux
Normal file
@@ -0,0 +1,31 @@
|
||||
EXEC1 = dhcpd
|
||||
OBJS1 = dhcpd.o arpping.o
|
||||
|
||||
EXEC2 = tools/makeiplist
|
||||
OBJS2 = tools/makeiplist.o
|
||||
|
||||
EXEC3 = tools/browseiplist
|
||||
OBJS3 = tools/browseiplist.o
|
||||
|
||||
|
||||
all: $(EXEC1) $(EXEC2) $(EXEC3)
|
||||
|
||||
|
||||
$(EXEC1): $(OBJS1)
|
||||
gcc $(OBJS1) -o $(EXEC1)
|
||||
|
||||
$(EXEC2): $(OBJS2)
|
||||
gcc $(OBJS2) -o $(EXEC2)
|
||||
|
||||
$(EXEC3): $(OBJS3)
|
||||
gcc $(OBJS3) -o $(EXEC3)
|
||||
|
||||
clean:
|
||||
-rm -f $(EXEC1) $(EXEC2) $(EXEC3) *.elf *.o core
|
||||
|
||||
$(OBJS1): dhcpd.h arpping.h
|
||||
|
||||
$(OBJS2):
|
||||
|
||||
$(OBJS3):
|
||||
|
15
Makefile.uClinux
Normal file
15
Makefile.uClinux
Normal file
@@ -0,0 +1,15 @@
|
||||
EXEC = dhcpd
|
||||
OBJS = dhcpd.o arpping.o
|
||||
|
||||
|
||||
all: $(EXEC)
|
||||
|
||||
$(EXEC): $(OBJS)
|
||||
$(LD) $(LDFLAGS) -o $@.elf $(OBJS) $(LDLIBS)
|
||||
$(CONVERT)
|
||||
|
||||
clean:
|
||||
-rm -f $(EXEC) *.elf *.o
|
||||
|
||||
$(OBJS): dhcpd.h
|
||||
|
80
README
Normal file
80
README
Normal file
@@ -0,0 +1,80 @@
|
||||
NETtel DHCP Server README
|
||||
-------------------------
|
||||
|
||||
The NETtel DHCP Server is designed to run on a NETtel (which
|
||||
runs on Greg Ungerer's uClinux-coldfire kernel) but will easily
|
||||
run on normal Linux distributions for PCs.
|
||||
|
||||
The NETtel DHCP Server is designed deliberately to be a small,
|
||||
lean, DHCP server. It does not implement the entire protocol
|
||||
but only what is necessary to serve the following:
|
||||
|
||||
IP address (and its subnet)
|
||||
Gateway address
|
||||
DNS Server address
|
||||
WINS (NetBIOS Name Server)
|
||||
|
||||
The lease times are hard coded to 10 days (from memory :-)
|
||||
|
||||
|
||||
The NETtel DHCP Server employs a number of simple config files:
|
||||
|
||||
dhcpd.iplist
|
||||
------------
|
||||
Binary list of ip addresses that the server may offer. This list may
|
||||
include ip addresses already leased out.
|
||||
|
||||
|
||||
dhcpd.leased
|
||||
------------
|
||||
Binary list of leased ip addresses and their respective MAC address.
|
||||
format:
|
||||
|
||||
16 byte MAC
|
||||
8 byte ip address
|
||||
16 byte MAC
|
||||
8 byte ip address
|
||||
.
|
||||
etc.
|
||||
|
||||
example: hexdump dhcpd.leases
|
||||
|
||||
0: 00 AB 00 00 00 00 00 00-00 FF 00 00 00 00 00 01 ................
|
||||
10: CB 18 97 78 00 BB 00 00-00 00 00 00 00 AA 00 00 ...x............
|
||||
20: 00 00 00 CC CB 18 97 79-00 80 5F 94 28 2A 00 00 .......y.._.(*..
|
||||
30: 00 00 00 00 00 00 00 00-CB 18 97 7A ...........z
|
||||
|
||||
dhcpd.conf
|
||||
----------
|
||||
|
||||
/etc/config> cat dhcpd.conf
|
||||
subnet 255.255.255.0
|
||||
router 203.24.151.121
|
||||
wins 203.50.0.24
|
||||
/etc/config>
|
||||
|
||||
|
||||
---
|
||||
DNS is grabbed from resolv.conf:
|
||||
nameserver x.x.x.x
|
||||
nameserver y.y.y.y
|
||||
nameserver z.z.z.z
|
||||
|
||||
Up to 3 DNS servers are supported.
|
||||
|
||||
---
|
||||
Q&A
|
||||
|
||||
|
||||
Q. Isn't this all very complicated for a lease/ip pool?
|
||||
A. yes.. but it saves space :-)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Have fun!
|
||||
-Moreton Bay DHCP Server development team.
|
||||
|
9
TODO
Normal file
9
TODO
Normal file
@@ -0,0 +1,9 @@
|
||||
TODO
|
||||
----
|
||||
+ if the number of simultaneous clients reaches MAX_SIMUL_CLIENTS the offer_num
|
||||
count will reset and previously OFFERed clients may be temporarily NAKed
|
||||
until the count stabalises
|
||||
+ little/big endian issue probable cause for segmentation fault on i86 platform
|
||||
+ makeiplist basic functionality works.. more user friendly interface required
|
||||
+ browseiplist incomplete
|
||||
+ better standard linux distro support
|
183
arpping.c
Normal file
183
arpping.c
Normal file
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* arpping.c
|
||||
*
|
||||
* Mostly stolen from: dhcpcd - DHCP client daemon
|
||||
* by Yoichi Hariguchi <yoichi@fore.com>
|
||||
*/
|
||||
|
||||
|
||||
#include "arpping.h"
|
||||
|
||||
#define DEBUG 0
|
||||
|
||||
|
||||
/* local prototypes */
|
||||
int arpCheck(u_long inaddr, struct ifinfo *ifbuf, long timeout);
|
||||
void mkArpMsg(int opcode, u_long tInaddr, u_char *tHaddr, u_long sInaddr, u_char *sHaddr, struct arpMsg *msg);
|
||||
int openRawSocket (int *s, u_short type);
|
||||
|
||||
|
||||
/* args: yiaddr - what IP to ping (eg. on the NETtel cb189701)
|
||||
* retn: 1 addr free
|
||||
* 0 addr used
|
||||
* -1 error
|
||||
*/
|
||||
int arpping(u_int32_t yiaddr) {
|
||||
int rv;
|
||||
struct ifinfo ifbuf;
|
||||
int n;
|
||||
static int nr = 0;
|
||||
unsigned char *ep;
|
||||
/*unsigned char ep[6] = {0x00,0xd0,0xcf,0x00,0x01,0x0f};*/
|
||||
|
||||
/*
|
||||
u_int32_t yiaddr = 0xcb189701;
|
||||
u_int32_t yiaddr = 0xcb189778;
|
||||
*/
|
||||
|
||||
strcpy(ifbuf.ifname, "eth0");
|
||||
ifbuf.addr = 0xcb1897aa; /* this addr appears to be irrelevant */
|
||||
/* ifbuf.mask = 0xffffff00;
|
||||
ifbuf.bcast = 0xcb1897ff; */
|
||||
ifbuf.mask = 0x0;
|
||||
ifbuf.bcast = 0x0;
|
||||
|
||||
#if CONFIG_NETtel
|
||||
/* rip the HW addr out of the flash :-)
|
||||
* points to the memory where hwaddr is located */
|
||||
ep = (unsigned char *) (0xf0006000);/* + (nr++ * 6));*/
|
||||
#if 0
|
||||
if ((ep[0] == 0xff) && (ep[1] == 0xff) && (ep[2] == 0xff) &&
|
||||
(ep[3] == 0xff) && (ep[4] == 0xff) && (ep[5] == 0xff)) {
|
||||
#if DEBUG
|
||||
syslog(LOG_INFO, "DHCPD - oops! bad hwaddr (0xff)");
|
||||
#endif
|
||||
return -1;
|
||||
} else if ((ep[0] == 0) && (ep[1] == 0) && (ep[2] == 0) &&
|
||||
(ep[3] == 0) && (ep[4] == 0) && (ep[5] == 0)) {
|
||||
#if DEBUG
|
||||
syslog(LOG_INFO, "DHCPD - oops! bad hwaddr (0x00)");
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
printf("arpping hwaddr: ");
|
||||
#endif
|
||||
for(n=0;n<6;n++) {
|
||||
#if 0
|
||||
printf("%02x", ep[n]);
|
||||
#endif
|
||||
ifbuf.haddr[n] = ep[n];
|
||||
}
|
||||
#if 0
|
||||
printf("\n");
|
||||
#endif
|
||||
ifbuf.flags = 0;
|
||||
|
||||
rv = arpCheck(yiaddr, &ifbuf, 3);
|
||||
#if 0
|
||||
printf("rv = %d (1=free, 0=used)\n", rv);
|
||||
#endif
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
int arpCheck(u_long inaddr, struct ifinfo *ifbuf, long timeout) {
|
||||
int s; /* socket */
|
||||
int rv; /* return value */
|
||||
struct sockaddr addr; /* for interface name */
|
||||
struct arpMsg arp;
|
||||
fd_set fdset;
|
||||
struct timeval tm;
|
||||
time_t prevTime;
|
||||
|
||||
rv = 1;
|
||||
openRawSocket(&s, ETH_P_ARP);
|
||||
|
||||
/* send arp request */
|
||||
mkArpMsg(ARPOP_REQUEST, inaddr, NULL, ifbuf->addr, ifbuf->haddr, &arp);
|
||||
bzero(&addr, sizeof(addr));
|
||||
strcpy(addr.sa_data, ifbuf->ifname);
|
||||
if ( sendto(s, &arp, sizeof(arp), 0, &addr, sizeof(addr)) < 0 ) {
|
||||
#if 0
|
||||
printf("sendto (arpCheck)");
|
||||
#endif
|
||||
rv = 0;
|
||||
}
|
||||
|
||||
/* wait arp reply, and check it */
|
||||
tm.tv_usec = 0;
|
||||
time(&prevTime);
|
||||
while ( timeout > 0 ) {
|
||||
FD_ZERO(&fdset);
|
||||
FD_SET(s, &fdset);
|
||||
tm.tv_sec = timeout;
|
||||
if ( select(s+1, &fdset, (fd_set *)NULL, (fd_set *)NULL, &tm) < 0 ) {
|
||||
#if 0
|
||||
printf("select (arpCheck)");
|
||||
#endif
|
||||
rv = 0;
|
||||
}
|
||||
if ( FD_ISSET(s, &fdset) ) {
|
||||
if (recv(s, &arp, sizeof(arp), 0) < 0 ) {
|
||||
#if 0
|
||||
printf("recv (arpCheck)");
|
||||
#endif
|
||||
rv = 0;
|
||||
}
|
||||
if(arp.operation == htons(ARPOP_REPLY) && bcmp(arp.tHaddr, ifbuf->haddr, 6) == 0 && *((u_int *)arp.sInaddr) == inaddr ) {
|
||||
rv = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
timeout -= time(NULL) - prevTime;
|
||||
time(&prevTime);
|
||||
}
|
||||
close(s);
|
||||
return rv;
|
||||
}
|
||||
|
||||
void mkArpMsg(int opcode, u_long tInaddr, u_char *tHaddr,
|
||||
u_long sInaddr, u_char *sHaddr, struct arpMsg *msg) {
|
||||
bzero(msg, sizeof(*msg));
|
||||
bcopy(MAC_BCAST_ADDR, msg->ethhdr.h_dest, 6); /* MAC DA */
|
||||
bcopy(sHaddr, msg->ethhdr.h_source, 6); /* MAC SA */
|
||||
msg->ethhdr.h_proto = htons(ETH_P_ARP); /* protocol type (Ethernet) */
|
||||
msg->htype = htons(ARPHRD_ETHER); /* hardware type */
|
||||
msg->ptype = htons(ETH_P_IP); /* protocol type (ARP message) */
|
||||
msg->hlen = 6; /* hardware address length */
|
||||
msg->plen = 4; /* protocol address length */
|
||||
msg->operation = htons(opcode); /* ARP op code */
|
||||
*((u_int *)msg->sInaddr) = sInaddr; /* source IP address */
|
||||
bcopy(sHaddr, msg->sHaddr, 6); /* source hardware address */
|
||||
*((u_int *)msg->tInaddr) = tInaddr; /* target IP address */
|
||||
if ( opcode == ARPOP_REPLY ) {
|
||||
bcopy(tHaddr, msg->tHaddr, 6); /* target hardware address */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int openRawSocket (int *s, u_short type) {
|
||||
int optval = 1;
|
||||
|
||||
if((*s = socket (AF_INET, SOCK_PACKET, htons (type))) == -1) {
|
||||
#if 0
|
||||
perror("socket");
|
||||
printf("socket err\n");
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(setsockopt (*s, SOL_SOCKET, SO_BROADCAST, &optval, sizeof (optval)) == -1) {
|
||||
#if 0
|
||||
perror("setsockopt");
|
||||
printf("setsockopt err\n");
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
50
arpping.h
Normal file
50
arpping.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* arpping .h
|
||||
*/
|
||||
|
||||
#ifndef ARPPING_H
|
||||
#define ARPPING_H
|
||||
|
||||
#define MAC_BCAST_ADDR "\xff\xff\xff\xff\xff\xff"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/if_arp.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
struct arpMsg {
|
||||
struct ethhdr ethhdr; /* Ethernet header */
|
||||
u_short htype; /* hardware type (must be ARPHRD_ETHER) */
|
||||
u_short ptype; /* protocol type (must be ETH_P_IP) */
|
||||
u_char hlen; /* hardware address length (must be 6) */
|
||||
u_char plen; /* protocol address length (must be 4) */
|
||||
u_short operation; /* ARP opcode */
|
||||
u_char sHaddr[6]; /* sender's hardware address */
|
||||
u_char sInaddr[4]; /* sender's IP address */
|
||||
u_char tHaddr[6]; /* target's hardware address */
|
||||
u_char tInaddr[4]; /* target's IP address */
|
||||
u_char pad[18]; /* pad for min. Ethernet payload (60 bytes) */
|
||||
};
|
||||
|
||||
struct ifinfo {
|
||||
char ifname[IFNAMSIZ];
|
||||
u_long addr; /* network byte order */
|
||||
u_long mask; /* network byte order */
|
||||
u_long bcast; /* network byte order */
|
||||
u_char haddr[6];
|
||||
short flags;
|
||||
};
|
||||
|
||||
|
||||
/* function prototypes */
|
||||
int arpping(u_int32_t yiaddr);
|
||||
|
||||
#endif
|
16
debug.c
Normal file
16
debug.c
Normal file
@@ -0,0 +1,16 @@
|
||||
/* debug.c -- DHCP server debug specific functions */
|
||||
|
||||
#include "debug.h"
|
||||
#include <syslog.h>
|
||||
|
||||
|
||||
#if DEBUG
|
||||
void print_chaddr(u_int8_t *chaddr,char *title) {
|
||||
syslog(LOG_INFO,"%s = %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x",
|
||||
title,chaddr[0],chaddr[1],chaddr[2],chaddr[4],
|
||||
chaddr[4],chaddr[5],chaddr[6],chaddr[7],
|
||||
chaddr[8],chaddr[9],chaddr[10],chaddr[11],
|
||||
chaddr[12],chaddr[13],chaddr[14],chaddr[15]);
|
||||
}
|
||||
#endif
|
||||
|
20
debug.h
Normal file
20
debug.h
Normal file
@@ -0,0 +1,20 @@
|
||||
/* debug.h */
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
#define DEBUG 0
|
||||
|
||||
#if DEBUG
|
||||
void print_chaddr(u_int8_t *chaddr, char *title);
|
||||
#endif
|
||||
|
806
dhcpd.c
Normal file
806
dhcpd.c
Normal file
@@ -0,0 +1,806 @@
|
||||
/* dhcpd.c
|
||||
*
|
||||
* Moreton Bay DHCP Server
|
||||
* Copyright (C) 1999 Matthew Ramsay <matthewr@moreton.com.au>
|
||||
* Chris Trew <ctrew@moreton.com.au>
|
||||
*
|
||||
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/stat.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#include <syslog.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#ifndef EMBED
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
|
||||
#include "debug.h"
|
||||
#include "dhcpd.h"
|
||||
#include "arpping.h"
|
||||
#include "socket.h"
|
||||
#include "options.h"
|
||||
#include "files.h"
|
||||
#include "nettel.h"
|
||||
|
||||
|
||||
/* prototypes */
|
||||
int log_pid();
|
||||
int getPacket(struct dhcpMessage *packet, int server_socket);
|
||||
int sendOffer(int client_socket, struct dhcpMessage *oldpacket);
|
||||
int sendNAK(int client_socket, struct dhcpMessage *oldpacket);
|
||||
int sendACK(int client_socket, struct dhcpMessage *oldpacket);
|
||||
u_int32_t findAddr(u_int8_t *chaddr, u_int32_t xid);
|
||||
int test_ip(u_int32_t ipaddr);
|
||||
u_int32_t freeIPAddresses(u_int32_t leased[],int num_leased);
|
||||
|
||||
|
||||
/* globals */
|
||||
struct dhcpOfferedAddr offeredAddr[MAX_SIMUL_CLIENTS];
|
||||
int offer_num = 0; /* how many offers we are currently serving */
|
||||
unsigned char server_ipaddr[4];
|
||||
|
||||
|
||||
int main() {
|
||||
int server_socket;
|
||||
int client_socket;
|
||||
int bytes;
|
||||
struct dhcpMessage packet;
|
||||
unsigned char *state, *hw_addr;
|
||||
unsigned char *server_id;
|
||||
int search_result;
|
||||
|
||||
/* server ip addr */
|
||||
int fd = -1;
|
||||
struct ifreq ifr;
|
||||
struct sockaddr_in *sin;
|
||||
|
||||
/* by default 10.10.10.10 -- server id */
|
||||
server_ipaddr[0] = 0xA;
|
||||
server_ipaddr[1] = 0xA;
|
||||
server_ipaddr[2] = 0xA;
|
||||
server_ipaddr[3] = 0xA;
|
||||
|
||||
openlog("dhcpd", 0, 0);
|
||||
syslog(LOG_INFO, "Moreton Bay DHCP Server (v%s) started", VERSION);
|
||||
log_pid();
|
||||
|
||||
if((fd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) >= 0) {
|
||||
strcpy(ifr.ifr_name, "eth0");
|
||||
ifr.ifr_addr.sa_family = AF_INET;
|
||||
if (ioctl(fd, SIOCGIFADDR, &ifr) == 0) {
|
||||
sin = (struct sockaddr_in *)&ifr.ifr_addr;
|
||||
#if EMBED
|
||||
sin->sin_addr.s_addr = htonl(sin->sin_addr.s_addr);
|
||||
#endif
|
||||
#if DEBUG
|
||||
syslog(LOG_INFO, "eth0 (server_ip) = %s", inet_ntoa(sin->sin_addr));
|
||||
#endif
|
||||
memcpy(server_ipaddr, &sin->sin_addr, 4);
|
||||
}
|
||||
}
|
||||
|
||||
while(1) { /* loop until universe collapses */
|
||||
server_socket = serverSocket(LISTEN_PORT);
|
||||
if(server_socket == -1) {
|
||||
syslog(LOG_ERR, "couldn't create server socket -- au revoir");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
bytes = getPacket(&packet, server_socket); /* this waits for a packet - idle */
|
||||
close(server_socket);
|
||||
if(bytes < 0)
|
||||
continue;
|
||||
|
||||
#ifdef CONFIG_NETtel
|
||||
/*******************************************************************************************/
|
||||
/* Now check to see if the request came from this NETtel.
|
||||
* if so we wish to ignore its cries for an address */
|
||||
if((state = getOption(packet.options, DHCP_CLIENT_ID)) == NULL) {
|
||||
#if DEBUG
|
||||
syslog(LOG_ERR, "couldnt get option from packet (CLIENT_ID) -- ignoring");
|
||||
syslog(LOG_ERR, "maybe RedHat pump is the client.. -- ignore missing CLIENT_ID");
|
||||
#endif
|
||||
} else {
|
||||
|
||||
state++; /* move pointer up as state[0] == ARPHRD_ETHER == 0x01 */
|
||||
hw_addr = (unsigned char *) (0xf0006000);
|
||||
|
||||
/* state should now be pointing to the hardware address as will
|
||||
* hw_addr which points to a memory location inside the nettel */
|
||||
#if DEBUG
|
||||
syslog(LOG_INFO, "state = %02x%02x%02x%02x%02x%02x",state[0],state[1],state[2],state[3],state[4],state[5]);
|
||||
syslog(LOG_INFO, "hw1 = %02x%02x%02x%02x%02x%02x",hw_addr[0],hw_addr[1],hw_addr[2],hw_addr[3],hw_addr[4],hw_addr[5]);
|
||||
syslog(LOG_INFO, "hw2 = %02x%02x%02x%02x%02x%02x",hw_addr[6],hw_addr[7],hw_addr[8],hw_addr[9],hw_addr[10],hw_addr[11]);
|
||||
#endif
|
||||
if(memcmp(hw_addr,state,6) == 0) {
|
||||
#if DEBUG
|
||||
syslog(LOG_INFO, "not responding to my other half self");
|
||||
#endif
|
||||
continue; /* skip everything and listen to another request */
|
||||
} else if(memcmp(hw_addr+6,state, 6) == 0) {
|
||||
#if DEBUG
|
||||
syslog(LOG_INFO, "not responding to my other half self");
|
||||
#endif
|
||||
continue; /* skip everything and listen to another request */
|
||||
}
|
||||
}
|
||||
/*******************************************************************************************/
|
||||
#endif
|
||||
|
||||
if((state = getOption(packet.options, DHCP_MESSAGE_TYPE)) == NULL) {
|
||||
#if DEBUG
|
||||
syslog(LOG_ERR, "couldnt get option from packet (MSG_TYPE) -- ignoring");
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NETtel
|
||||
/* 1. why don't we add a 'route add -host allones eth0' here as
|
||||
* an experiment.
|
||||
* 2. we should lock the DHCP client from working until route_del_host()
|
||||
*/
|
||||
route_add_host(ADD);
|
||||
#endif
|
||||
|
||||
if((client_socket = clientSocket(LISTEN_PORT, SEND_PORT)) == -1) {
|
||||
syslog(LOG_ERR, "couldn't create client socket -- i'll try again");
|
||||
continue;
|
||||
}
|
||||
|
||||
switch(state[0]) {
|
||||
case DHCPDISCOVER:
|
||||
#if DEBUG
|
||||
syslog(LOG_INFO,"received DISCOVER");
|
||||
#endif
|
||||
if(sendOffer(client_socket, &packet) == -1) {
|
||||
syslog(LOG_ERR, "send OFFER failed -- ignoring");
|
||||
close(client_socket);
|
||||
continue; /* error occoured */
|
||||
}
|
||||
break;
|
||||
|
||||
case DHCPREQUEST:
|
||||
#if DEBUG
|
||||
syslog(LOG_INFO,"received REQUEST");
|
||||
#endif
|
||||
server_id = getOption(packet.options, 0x36);
|
||||
if(server_id == NULL) {
|
||||
#if DEBUG
|
||||
syslog(LOG_INFO, "get option on 0x36 failed! NAKing");
|
||||
#endif
|
||||
sendNAK(client_socket, &packet);
|
||||
/* Let's send an offer as well */
|
||||
if(sendOffer(client_socket, &packet) == -1) {
|
||||
syslog(LOG_ERR, "send OFFER failed -- ignoring");
|
||||
close(client_socket);
|
||||
continue; /* error occoured */
|
||||
}
|
||||
} else {
|
||||
#if DEBUG
|
||||
syslog(LOG_INFO, "server_id = %02x%02x%02x%02x", server_id[0], server_id[1],
|
||||
server_id[2], server_id[3]);
|
||||
#endif
|
||||
if(memcmp(server_id, server_ipaddr, 4) == 0) {
|
||||
if (sendACK(client_socket, &packet) == -1)
|
||||
sendNAK(client_socket, &packet);
|
||||
} else {
|
||||
sendNAK(client_socket, &packet);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
syslog(LOG_WARNING, "unsupported DHCP message (%02x) -- ignoring", state[0]);
|
||||
}
|
||||
|
||||
close(client_socket);
|
||||
#ifdef CONFIG_NETtel
|
||||
route_add_host(DEL); /* what the hell is this */
|
||||
#endif
|
||||
}
|
||||
|
||||
/* should never executes */
|
||||
syslog(LOG_ERR, "exit");
|
||||
closelog();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int log_pid() {
|
||||
int fd;
|
||||
pid_t pid;
|
||||
char *pidfile = PID_FILE;
|
||||
|
||||
pid = getpid();
|
||||
if((fd = open(pidfile, O_WRONLY | O_CREAT, 0660)) < 0)
|
||||
return -1;
|
||||
write(fd, (void *) &pid, sizeof(pid));
|
||||
close(fd);
|
||||
}
|
||||
|
||||
|
||||
int getPacket(struct dhcpMessage *packet, int server_socket) {
|
||||
char buf[sizeof(struct dhcpMessage)];
|
||||
u_int32_t magic;
|
||||
int bytes;
|
||||
|
||||
#if DEBUG
|
||||
syslog(LOG_INFO, "listening for any DHCP messages on network...");
|
||||
#endif
|
||||
memset(buf, 0, sizeof(buf));
|
||||
bytes = read(server_socket, (char *)buf, sizeof(buf));
|
||||
if(bytes < 0) {
|
||||
#if DEBUG
|
||||
syslog(LOG_INFO, "couldn't read on server socket -- ignoring");
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(packet, buf, sizeof(buf));
|
||||
memcpy(&magic, &packet->cookie, 4);
|
||||
if(htonl(magic) != MAGIC) {
|
||||
syslog(LOG_ERR, "client sent bogus message -- ignoring");
|
||||
return -1;
|
||||
}
|
||||
#if DEBUG
|
||||
syslog(LOG_INFO, "oooooh!!! got some!");
|
||||
#endif
|
||||
return bytes;
|
||||
}
|
||||
|
||||
|
||||
/* send a DHCP OFFER to a DHCP DISCOVER */
|
||||
int sendOffer(int client_socket, struct dhcpMessage *oldpacket) {
|
||||
FILE *in;
|
||||
struct dhcpMessage packet;
|
||||
char buf[sizeof(struct dhcpMessage)];
|
||||
int bytes;
|
||||
int n,k;
|
||||
int address_used = FALSE;
|
||||
int found_one = FALSE;
|
||||
char tmp[32];
|
||||
struct in_addr inp;
|
||||
|
||||
memset(&packet, 0, sizeof(packet));
|
||||
|
||||
packet.op = BOOTREPLY;
|
||||
packet.htype = ETH_10MB;
|
||||
packet.hlen = ETH_10MB_LEN;
|
||||
packet.xid = oldpacket->xid;
|
||||
if((packet.yiaddr = findAddr(oldpacket->chaddr, oldpacket->xid)) == 0) {
|
||||
syslog(LOG_WARNING, "no IP addresses to give -- OFFER abandoned");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(&packet.chaddr, oldpacket->chaddr, 16);
|
||||
memcpy(&packet.cookie, "\x63\x82\x53\x63", 4);
|
||||
memcpy(&packet.options, "\xff", 1);
|
||||
|
||||
addOption(packet.options, 0x35, 0x01, "\x02");
|
||||
addOption(packet.options, 0x36, 0x04, server_ipaddr);
|
||||
|
||||
/* lease time */
|
||||
addOption(packet.options, 0x33, 0x04, LEASE_TIME);
|
||||
|
||||
/* subnet */
|
||||
if((search_config_file(DHCPD_CONF_FILE, "subnet", tmp)) == 1) {
|
||||
inet_aton(tmp, &inp);
|
||||
addOption(packet.options, 0x01, 0x04, (char *)&inp.s_addr);
|
||||
}
|
||||
|
||||
/* gateway */
|
||||
if((search_config_file(DHCPD_CONF_FILE, "router", tmp)) == 1) {
|
||||
inet_aton(tmp, &inp);
|
||||
addOption(packet.options, 0x03, 0x04, (char *)&inp.s_addr);
|
||||
}
|
||||
|
||||
memcpy(buf, &packet, sizeof(packet));
|
||||
|
||||
#if DEBUG
|
||||
syslog(LOG_INFO, "sending OFFER");
|
||||
#endif
|
||||
bytes = send(client_socket, buf, sizeof(buf), 0);
|
||||
if(bytes == -1) {
|
||||
#if DEBUG
|
||||
syslog(LOG_ERR, "couldn't write to client_socket -- OFFER abandoned");
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int sendNAK(int client_socket, struct dhcpMessage *oldpacket) {
|
||||
struct dhcpMessage packet;
|
||||
char buf[sizeof(struct dhcpMessage)];
|
||||
int bytes;
|
||||
|
||||
memset(&packet, 0, sizeof(packet));
|
||||
|
||||
packet.op = BOOTREPLY;
|
||||
packet.htype = ETH_10MB;
|
||||
packet.hlen = ETH_10MB_LEN;
|
||||
packet.xid = oldpacket->xid;
|
||||
memcpy(&packet.chaddr, oldpacket->chaddr, 16);
|
||||
memcpy(&packet.cookie, "\x63\x82\x53\x63", 4);
|
||||
memcpy(&packet.options, "\xff", 1);
|
||||
/* options should look like this:
|
||||
* 0x350106 -- NAK
|
||||
* 0x3604serverid - server id */
|
||||
addOption(packet.options, 0x35, 0x01, "\x06");
|
||||
addOption(packet.options, 0x36, 0x04, server_ipaddr);
|
||||
|
||||
memcpy(buf, &packet, sizeof(packet));
|
||||
#if DEBUG
|
||||
syslog(LOG_INFO, "sending NAK");
|
||||
#endif
|
||||
bytes = send(client_socket, buf, sizeof(buf), 0);
|
||||
|
||||
if(bytes == -1) {
|
||||
#if DEBUG
|
||||
syslog(LOG_ERR, "error writing to client -- NAK abandoned");
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int sendACK(int client_socket, struct dhcpMessage *oldpacket) {
|
||||
struct dhcpMessage packet;
|
||||
char buf[sizeof(struct dhcpMessage)];
|
||||
int bytes;
|
||||
int k;
|
||||
char tmp[96];
|
||||
char tmp1[32];
|
||||
char tmp2[32];
|
||||
char tmp3[32];
|
||||
struct in_addr inp;
|
||||
struct in_addr inp1;
|
||||
struct in_addr inp2;
|
||||
struct in_addr inp3;
|
||||
int result = FALSE;
|
||||
int num;
|
||||
|
||||
memset(&packet, 0, sizeof(packet));
|
||||
|
||||
packet.op = BOOTREPLY;
|
||||
packet.htype = ETH_10MB;
|
||||
packet.hlen = ETH_10MB_LEN;
|
||||
packet.xid = oldpacket->xid;
|
||||
packet.ciaddr = oldpacket->ciaddr;
|
||||
memcpy(&packet.chaddr, oldpacket->chaddr, 16);
|
||||
memcpy(&packet.chaddr, oldpacket->chaddr, 16);
|
||||
memcpy(&packet.cookie, "\x63\x82\x53\x63", 4);
|
||||
memcpy(&packet.options, "\xff", 1);
|
||||
|
||||
/* loop thru offeredAddr to find which addr we
|
||||
* offered this client */
|
||||
#if DEBUG
|
||||
syslog(LOG_INFO, "cycling thru offered array of size %d", offer_num);
|
||||
#endif
|
||||
for(k=0;k<offer_num;k++) { /* cycle through the offered array */
|
||||
if(memcmp(offeredAddr[k].chaddr,packet.chaddr, 16) == 0) {
|
||||
#if DEBUG
|
||||
syslog(LOG_INFO, "chaddr matches what I have in my internel offer array");
|
||||
#endif
|
||||
packet.yiaddr = offeredAddr[k].yiaddr;
|
||||
inp.s_addr = packet.yiaddr;
|
||||
#if DEBUG
|
||||
syslog(LOG_INFO,"i'll attempt to ACK with ip_addr %s", inet_ntoa(inp));
|
||||
#else
|
||||
syslog(LOG_INFO,"serving %s", inet_ntoa(inp));
|
||||
#endif
|
||||
offeredAddr[k].yiaddr = offeredAddr[offer_num-1].yiaddr;
|
||||
memcpy(offeredAddr[k].chaddr, offeredAddr[offer_num-1].chaddr, 16);
|
||||
offer_num--;
|
||||
result = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (result != TRUE) { /* if we cant find it in the offered array somthing has gone wrong */
|
||||
syslog(LOG_ERR, "couldn't find in offer array -- ACK abandoned");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* options should look like this:
|
||||
* 0x350106 -- NAK
|
||||
* 0x3604 serverid - server id */
|
||||
addOption(packet.options, 0x35, 0x01, "\x05");
|
||||
addOption(packet.options, 0x36, 0x04, server_ipaddr);
|
||||
addOption(packet.options, 0x33, 0x04, LEASE_TIME);
|
||||
|
||||
/* subnet */
|
||||
if((search_config_file(DHCPD_CONF_FILE, "subnet", tmp)) == 1) {
|
||||
inet_aton(tmp, &inp);
|
||||
addOption(packet.options, 0x01, 0x04, (char *)&inp.s_addr);
|
||||
}
|
||||
|
||||
/* gateway */
|
||||
if((search_config_file(DHCPD_CONF_FILE, "router", tmp)) == 1) {
|
||||
inet_aton(tmp, &inp);
|
||||
addOption(packet.options, 0x03, 0x04, (char *)&inp.s_addr);
|
||||
}
|
||||
|
||||
/* DNS */
|
||||
#ifdef CONFIG_NETtel
|
||||
if((num = get_multiple_entries("/etc/config/resolv.conf", "nameserver", tmp1, tmp2, tmp3)) > 0) {
|
||||
#else
|
||||
if((num = get_multiple_entries("/etc/resolv.conf", "nameserver", tmp1,tmp2,tmp3)) > 0) {
|
||||
#endif
|
||||
if(num>0) {
|
||||
inet_aton(tmp1, &inp1);
|
||||
if(num>1) {
|
||||
inet_aton(tmp2, &inp2);
|
||||
if(num>2) {
|
||||
inet_aton(tmp3, &inp3);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(num == 1) {
|
||||
add_multiple_option(packet.options, 0x06, 0x04, (char *)&inp1.s_addr, NULL, NULL);
|
||||
} else if(num == 2) {
|
||||
add_multiple_option(packet.options, 0x06, 0x08, (char *)&inp1.s_addr, (char *)&inp2.s_addr, NULL);
|
||||
} else if (num == 3) {
|
||||
add_multiple_option(packet.options, 0x06, 0x0c, (char *)&inp1.s_addr, (char *)&inp2.s_addr, (char *)&inp3.s_addr);
|
||||
}
|
||||
}
|
||||
|
||||
/* WINS */
|
||||
if((search_config_file(DHCPD_CONF_FILE, "wins", tmp)) == 1) {
|
||||
inet_aton(tmp, &inp);
|
||||
addOption(packet.options, 0x2C, 0x04, (char *)&inp.s_addr);
|
||||
}
|
||||
|
||||
memcpy(buf, &packet, sizeof(packet));
|
||||
#if DEBUG
|
||||
syslog(LOG_INFO, "sending ACK");
|
||||
#endif
|
||||
bytes = send(client_socket, buf, sizeof(buf), 0);
|
||||
|
||||
if(bytes == -1) {
|
||||
#if DEBUG
|
||||
syslog(LOG_ERR, "error writing to client_socket -- ACK abandoned");
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* write new ip to lease section of config file
|
||||
* check that we dont write a lease that is already in the
|
||||
* lease file (ie. reusing address since MAC is the same
|
||||
* if it came from the lease file already dont re add it */
|
||||
if(check_if_already_leased(packet.yiaddr) == 0) {
|
||||
addLeased(packet.yiaddr, packet.chaddr);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NETtel
|
||||
if(commitChanges() == -1)
|
||||
return -1;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
u_int32_t findAddr(u_int8_t *chaddr, u_int32_t xid) {
|
||||
u_int32_t yiaddr = 0;
|
||||
u_int32_t iplist[MAX_IP_ADDR];
|
||||
u_int32_t leased[MAX_IP_ADDR];
|
||||
FILE *in = NULL;
|
||||
int n = 0;
|
||||
int k,i;
|
||||
size_t items; /* return value for fread */
|
||||
int num_ip_addr;
|
||||
int num_leased;
|
||||
u_int8_t mac_addr[16];
|
||||
u_int32_t ip_addr;
|
||||
int ip_leased = FALSE; /* is the addressed leased? */
|
||||
int already_in_offered = FALSE;
|
||||
|
||||
/* see if this chaddr is in the offered pool first */
|
||||
/* don't add this addr to offeredAddr if chaddr already in there! */
|
||||
/* win95 has a bad habbit of changing xid's halfway thru a conversation */
|
||||
for(n=0;n<offer_num;n++) {
|
||||
if(memcmp(offeredAddr[n].chaddr,chaddr,16) == 0) {
|
||||
#if DEBUG
|
||||
syslog(LOG_INFO, "chaddr already in offer array");
|
||||
#endif
|
||||
already_in_offered = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (already_in_offered == TRUE) {
|
||||
#if DEBUG
|
||||
syslog(LOG_INFO, "i've already offered you an address -- have it again (%x)", offeredAddr[n].yiaddr);
|
||||
#endif
|
||||
return offeredAddr[n].yiaddr;
|
||||
} else {
|
||||
#if DEBUG
|
||||
syslog(LOG_INFO, "searching for new address for new client");
|
||||
#endif
|
||||
}
|
||||
|
||||
/* open up dhcpd.iplist */
|
||||
if((in = fopen(DHCPD_IPLIST_FILE, "r")) == NULL) {
|
||||
syslog(LOG_ERR, "%s not found -- no IP pool to draw from", DHCPD_IPLIST_FILE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Read in all the values into the iplist Array*/
|
||||
while(TRUE) {
|
||||
items = fread(&iplist[n++], sizeof(u_int32_t), 1, in);
|
||||
if(items < 1)
|
||||
break;
|
||||
}
|
||||
fclose(in);
|
||||
|
||||
num_ip_addr = n-1;
|
||||
|
||||
if((in = fopen(DHCPD_LEASES_FILE, "r")) == NULL) {
|
||||
#if DEBUG
|
||||
syslog(LOG_WARNING, "dhcpd.leases not found -- no leases");
|
||||
#endif
|
||||
}
|
||||
|
||||
n=0;
|
||||
/* Read in the mac - IP pair from the leases file */
|
||||
while(TRUE) {
|
||||
if(in == NULL)
|
||||
break;
|
||||
items = fread(&mac_addr, sizeof(mac_addr), 1, in);
|
||||
if(items < 1)
|
||||
break;
|
||||
items = fread(&ip_addr, sizeof(ip_addr), 1, in);
|
||||
if(items < 1)
|
||||
break;
|
||||
#if DEBUG
|
||||
syslog(LOG_INFO,"file yielded valid MAC/IP pair - ip_addr = %x", ip_addr);
|
||||
print_chaddr(mac_addr,"MAC");
|
||||
print_chaddr(mac_addr,"CDR");
|
||||
#endif
|
||||
if(memcmp(mac_addr, chaddr, sizeof(mac_addr)) == 0) {
|
||||
#if DEBUG
|
||||
syslog(LOG_INFO, "hey! i've seen you around before...");
|
||||
#endif
|
||||
/* ooh! the connecting clients MAC address
|
||||
* is already in lease file!! let's offer him
|
||||
* the address he used last time */
|
||||
#if DEBUG
|
||||
syslog(LOG_INFO, "i found an address you've used before.. have it again");
|
||||
#endif
|
||||
memcpy(offeredAddr[offer_num].chaddr,chaddr,16);
|
||||
offeredAddr[offer_num].yiaddr = ip_addr;
|
||||
if(offer_num < MAX_SIMUL_CLIENTS)
|
||||
offer_num++;
|
||||
else {
|
||||
syslog(LOG_ERR, "Ahhh!! i'm not configured to handle that many simultaneous clients!!");
|
||||
syslog(LOG_ERR, "I'm resetteing my offer count and trying again");
|
||||
offer_num=0;
|
||||
}
|
||||
return ip_addr;
|
||||
} else {
|
||||
/* Add it to the array for later comparison between available leases
|
||||
* and the ones that are already leased */
|
||||
#if DEBUG
|
||||
syslog(LOG_INFO, "added lease to array");
|
||||
#endif
|
||||
leased[n++] = ip_addr;
|
||||
}
|
||||
}
|
||||
if(in != NULL)
|
||||
fclose(in);
|
||||
|
||||
num_leased = n;
|
||||
|
||||
/* compare the leased addresses with the actual list and
|
||||
* find the first free address */
|
||||
/* also check the offeredAddr array so we don't offer the same
|
||||
* addr to simultaneously connecting clients */
|
||||
for(n=0;n<num_ip_addr;n++) {
|
||||
for(k=0;k<num_leased;k++) {
|
||||
if(iplist[n] == leased[k]) {
|
||||
/* address already leased */
|
||||
#if DEBUG
|
||||
syslog(LOG_INFO, "address %x is already leased... skipping", iplist[n]);
|
||||
#endif
|
||||
ip_leased = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(ip_leased == FALSE) { /* if the ip wasnt leased */
|
||||
/* check that it is not in offered list */
|
||||
for(i=0;i<offer_num;i++) { /* cycle thru offered array */
|
||||
if(iplist[n] == offeredAddr[i].yiaddr) { /* already there.. hand it out again */
|
||||
if (memcmp(offeredAddr[i].chaddr,chaddr,16) == 0) {
|
||||
#if DEBUG
|
||||
syslog(LOG_INFO, "already in offered array.. have it again!");
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
#if DEBUG
|
||||
syslog(LOG_INFO, "address already offered but not yet cleared..");
|
||||
#endif
|
||||
ip_leased = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(ip_leased == FALSE) {
|
||||
/* Now we test to see if the address is actually currently taken
|
||||
* if it is we should also set it to leased in the leased file */
|
||||
#if EMBED
|
||||
if (test_ip(iplist[n]) == 0) {
|
||||
/* it passed the test you are free to have it */
|
||||
#if DEBUG
|
||||
syslog(LOG_INFO, "address arped and is free");
|
||||
#endif
|
||||
yiaddr = iplist[n]; /* after setting the yiaddr for testing later */
|
||||
break;/* breaks outer loop */
|
||||
}
|
||||
#if DEBUG
|
||||
else {
|
||||
/* looks like that IP is taken */
|
||||
syslog(LOG_INFO, "free IP is not so free...");
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
yiaddr = iplist[n];
|
||||
#endif
|
||||
} else {
|
||||
#if DEBUG
|
||||
syslog(LOG_INFO, "sorry.. another simultaneous client has been offered this address..");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
ip_leased = FALSE;
|
||||
}
|
||||
|
||||
/* If you wanted you could compare the num ip addresses leased (num_leased) to
|
||||
* the total num ip addresses (num_ip_addr) and determine a ratio to start
|
||||
* freeing up ip addresses -- HERE */
|
||||
|
||||
if(yiaddr == 0) {
|
||||
/* no free ip addresses remain */
|
||||
#if DEBUG
|
||||
syslog(LOG_INFO, "no free IP addresses found in pool -- attempting to free one");
|
||||
#endif
|
||||
|
||||
/* If the ip addresses are full then there is somthing wrong
|
||||
* It will only occour when a network card has been replaced on a machine thus
|
||||
* is very rare or there are more machines than addresses which is stoopid that
|
||||
* is why we should only check this when the list is full and a machine is
|
||||
* requesting an IP address.
|
||||
* Also Arp.c should be checked to make sure all addresses are correct */
|
||||
#if EMBED
|
||||
if ((yiaddr = freeIPAddresses(leased,num_leased)) == 0) { /* No IP addresses could be freed */
|
||||
#if DEBUG
|
||||
syslog(LOG_ERR, "couldn't free any IP addresses -- add more to pool");
|
||||
#endif
|
||||
} else {
|
||||
#if DEBUG
|
||||
syslog(LOG_INFO, "i found a freeable IP address.. let's use that");
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
syslog(LOG_INFO, "out of IP addresses -- add more to pool");
|
||||
#endif
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
syslog(LOG_INFO, "the IP address i'll use is %x", yiaddr);
|
||||
#endif
|
||||
|
||||
memcpy(offeredAddr[offer_num].chaddr,chaddr,16); /* cp chaddr to offered array */
|
||||
offeredAddr[offer_num].yiaddr = yiaddr;
|
||||
if(offer_num < MAX_SIMUL_CLIENTS)
|
||||
offer_num++;
|
||||
else {
|
||||
syslog(LOG_ERR, "Ahhh!! i'm not configured to handle that many simultaneous clients!!");
|
||||
syslog(LOG_ERR, "I'm resetteing my offer count and trying again");
|
||||
offer_num=0;
|
||||
}
|
||||
return yiaddr;
|
||||
}
|
||||
|
||||
|
||||
u_int32_t freeIPAddresses (u_int32_t leased[],int num_leased) {
|
||||
int i;
|
||||
int found;
|
||||
|
||||
for(i=0;i<num_leased;i++) {
|
||||
#if EMBED
|
||||
found = arpping(htonl(leased[i]));
|
||||
#else
|
||||
found = arpping(leased[i]);
|
||||
#endif
|
||||
if (found == 1) { /* if free address */
|
||||
/* if it timed out without a response */
|
||||
#if DEBUG
|
||||
syslog(LOG_INFO, "i found a spare address %x",leased[i]);
|
||||
#endif
|
||||
return(leased[i]);
|
||||
break;
|
||||
} else if (found == 0) { /* address used */
|
||||
#if DEBUG
|
||||
syslog(LOG_INFO, "address already active - %x",leased[i]);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return 0; /* Address not found */
|
||||
}
|
||||
|
||||
|
||||
/* Tests a free ip to check that it is not actually leased if it is it will
|
||||
* add the lease to the lease file and return 1
|
||||
* ret: 0 on success (not leased to another party )
|
||||
* 1 on success (actually leased to another party but lease file successfully updated)
|
||||
* -1 error */
|
||||
int test_ip(u_int32_t ipaddr) {
|
||||
int found;
|
||||
u_int8_t chaddr[16] = {0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00};
|
||||
|
||||
#if DEBUG
|
||||
syslog(LOG_INFO, "pinging IP to see if leased");
|
||||
#endif
|
||||
|
||||
#if EMBED
|
||||
found = arpping(htonl(ipaddr));
|
||||
#else
|
||||
found = arpping(ipaddr);
|
||||
#endif
|
||||
|
||||
#if DEBUG
|
||||
syslog(LOG_INFO, "arpping returned %d", found);
|
||||
#endif
|
||||
|
||||
if (found == 1) { /* if free address */
|
||||
/*if it timed out without a response*/
|
||||
#if DEBUG
|
||||
syslog(LOG_INFO, "IP is free to use");
|
||||
#endif
|
||||
return 0;
|
||||
} else if (found == 0) { /* address is used */
|
||||
#if DEBUG
|
||||
syslog(LOG_INFO, "IP is NOT free to use");
|
||||
#endif
|
||||
/* now go add it to the leased file. */
|
||||
if (addLeased(ipaddr, chaddr) == -1) {
|
||||
return 1;
|
||||
}
|
||||
#if DEBUG
|
||||
else {
|
||||
syslog(LOG_INFO, "IP address leased and HW is zerod");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
87
dhcpd.h
Normal file
87
dhcpd.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/* dhcpd.h */
|
||||
|
||||
#define VERSION "0.8.29"
|
||||
|
||||
/************************************/
|
||||
/* Defaults _you_ may want to tweak */
|
||||
/************************************/
|
||||
|
||||
#define MAX_SIMUL_CLIENTS 16 /* maximum number of simultaneous clients */
|
||||
|
||||
/* the period of time the client is allowed to use that address */
|
||||
#define LEASE_TIME "\x00\x0d\x2f\x00"
|
||||
|
||||
/* where to find the DHCP server files */
|
||||
#define DHCPD_CONF_FILE "/etc/config/dhcpd.conf"
|
||||
#define DHCPD_IPLIST_FILE "/etc/config/dhcpd.iplist"
|
||||
#define DHCPD_LEASES_FILE "/etc/config/dhcpd.leases"
|
||||
#define PID_FILE "/var/log/dhcpd.pid"
|
||||
|
||||
|
||||
/*****************************************************************/
|
||||
/* Do not modify below here unless you know what you are doing!! */
|
||||
/*****************************************************************/
|
||||
|
||||
/* DHCP protocol -- see RFC */
|
||||
#define LISTEN_PORT 67
|
||||
#define SEND_PORT 68
|
||||
|
||||
#define MAGIC 0x63825363
|
||||
|
||||
#define DHCP_MESSAGE_TYPE 0x35
|
||||
#define DHCP_SERVER_ID 0x36
|
||||
#define DHCP_CLIENT_ID 0x3d
|
||||
|
||||
#define BOOTREQUEST 1
|
||||
#define BOOTREPLY 2
|
||||
|
||||
#define ETH_10MB 1
|
||||
#define ETH_10MB_LEN 6
|
||||
|
||||
#define DHCPDISCOVER 1
|
||||
#define DHCPOFFER 2
|
||||
#define DHCPREQUEST 3
|
||||
#define DHCPDECLINE 4
|
||||
#define DHCPACK 5
|
||||
#define DHCPNAK 6
|
||||
#define DHCPRELEASE 7
|
||||
|
||||
/* miscellaneous defines */
|
||||
#define IPLIST 0
|
||||
#define LEASED 1
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#define MAX_BUF_SIZE 20 /* max xxx.xxx.xxx.xxx-xxx\n */
|
||||
#define MAX_IP_ADDR 254
|
||||
#define ADD 1
|
||||
#define DEL 2
|
||||
|
||||
struct dhcpMessage {
|
||||
u_int8_t op;
|
||||
u_int8_t htype;
|
||||
u_int8_t hlen;
|
||||
u_int8_t hops;
|
||||
u_int32_t xid;
|
||||
u_int16_t secs;
|
||||
u_int16_t flags;
|
||||
u_int32_t ciaddr;
|
||||
u_int32_t yiaddr;
|
||||
u_int32_t siaddr;
|
||||
u_int32_t giaddr;
|
||||
u_int8_t chaddr[16];
|
||||
u_int8_t sname[64];
|
||||
u_int8_t file[128];
|
||||
u_int32_t cookie;
|
||||
#ifdef EMBED
|
||||
u_int8_t options[128]; /* should be 308 but have to conserve space :-) */
|
||||
#else
|
||||
u_int8_t options[308];
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
struct dhcpOfferedAddr {
|
||||
u_int8_t chaddr[16];
|
||||
u_int32_t yiaddr;
|
||||
};
|
||||
|
142
files.c
Normal file
142
files.c
Normal file
@@ -0,0 +1,142 @@
|
||||
/* files.c -- DHCP server file manipulation */
|
||||
|
||||
#include "debug.h"
|
||||
#include "dhcpd.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <syslog.h>
|
||||
|
||||
|
||||
int get_multiple_entries(char *hay, char *needle, char *tmp1, char *tmp2, char *tmp3) {
|
||||
int num=0;
|
||||
FILE *in;
|
||||
int len;
|
||||
char buffer[32], w[32], v[32];
|
||||
|
||||
#if DEBUG
|
||||
syslog(LOG_ERR, "get_multiple_entries of %s from %s", needle, hay);
|
||||
#endif
|
||||
if ((in = fopen(hay, "r")) == NULL)
|
||||
return -1;
|
||||
|
||||
while((fgets(buffer, 32 - 1, in)) != NULL) {
|
||||
/* check if it's what we want */
|
||||
if((sscanf(buffer, "%s %s", w, v) >= 1) && (strcmp(w, needle) == 0)) {
|
||||
if(num == 0) {
|
||||
strcpy(tmp1, v);
|
||||
num++;
|
||||
} else if(num == 1) {
|
||||
strcpy(tmp2, v);
|
||||
num++;
|
||||
} else if(num == 2) {
|
||||
strcpy(tmp3, v);
|
||||
num++;
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(in);
|
||||
#if DEBUG
|
||||
syslog(LOG_INFO, "num=%d, tmp=%s, tmp2=%s, tmp3=%s", num, tmp1, tmp2, tmp3);
|
||||
#endif
|
||||
return num;
|
||||
}
|
||||
|
||||
|
||||
/* opens up dhcpd.leases and looks for yiaddr.. returning
|
||||
* 1 if it finds it, 0 if not. */
|
||||
int check_if_already_leased(u_int32_t yiaddr) {
|
||||
u_int32_t lease;
|
||||
FILE *in;
|
||||
int n = 0;
|
||||
u_int8_t mac_addr[16];
|
||||
u_int32_t ip_addr;
|
||||
int num_ip_addr;
|
||||
size_t items; /* return value for fread */
|
||||
|
||||
if((in = fopen(DHCPD_LEASES_FILE, "r")) == NULL) {
|
||||
#if DEBUG
|
||||
syslog(LOG_ERR, "dhcpd.leases not found -- no defined leases");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Read in the mac - IP pair from the leases file */
|
||||
while(TRUE) {
|
||||
items = fread(&mac_addr, sizeof(mac_addr), 1, in);
|
||||
if(items < 1)
|
||||
break;
|
||||
items = fread(&ip_addr, sizeof(ip_addr), 1, in);
|
||||
if(items < 1)
|
||||
break;
|
||||
#if DEBUG
|
||||
syslog(LOG_INFO,"got a valid MAC/IP pair from dhcpd.leases");
|
||||
syslog(LOG_INFO,"ip_addr taken = %x", ip_addr);
|
||||
#endif
|
||||
/* check if yiaddr matches ip_addr */
|
||||
if(ip_addr == yiaddr) {
|
||||
/* ip already in lease file */
|
||||
fclose(in);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
fclose(in);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int addLeased(u_int32_t yiaddr, u_int8_t *chaddr) {
|
||||
FILE *in;
|
||||
#if DEBUG
|
||||
syslog(LOG_INFO,"Writing new lease to lease file (IP = %08x)",yiaddr);
|
||||
print_chaddr(chaddr,"MAC");
|
||||
#endif
|
||||
if ((in = fopen(DHCPD_LEASES_FILE, "a")) == NULL)
|
||||
return -1;
|
||||
fwrite(chaddr, 16, 1, in);
|
||||
fwrite(&yiaddr, sizeof(u_int32_t), 1, in);
|
||||
fclose(in);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* This function opens up the file specified 'filename' and searches
|
||||
* through the file for 'keyword'. If 'keyword' is found any string
|
||||
* following it is stored in 'value'.. If 'value' is NULL we assume
|
||||
* the function was called simply to determing if the keyword exists
|
||||
* in the file.
|
||||
*
|
||||
* args: filename (IN) - config filename
|
||||
* keyword (IN) - word to search for in config file
|
||||
* value (OUT) - value of keyword (if value not NULL)
|
||||
*
|
||||
* retn: -1 on error,
|
||||
* 0 if keyword not found,
|
||||
* 1 if found
|
||||
*/
|
||||
int search_config_file(char *filename, char *keyword, char *value) {
|
||||
FILE *in;
|
||||
int len;
|
||||
char buffer[32], w[32], v[32];
|
||||
|
||||
if ((in = fopen(filename, "r")) == NULL)
|
||||
return -1;
|
||||
|
||||
while((fgets(buffer, 32 - 1, in)) != NULL) {
|
||||
/* check if it's what we want */
|
||||
if((sscanf(buffer, "%s %s", w, v) >= 1) && (strcmp(w, keyword) == 0)) {
|
||||
/* found it :-) */
|
||||
if(value == NULL) {
|
||||
return 1;
|
||||
} else {
|
||||
strcpy(value, v);
|
||||
fclose(in);
|
||||
/* tell them we got it */
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(in);
|
||||
return 0;
|
||||
}
|
7
files.h
Normal file
7
files.h
Normal file
@@ -0,0 +1,7 @@
|
||||
/* files.h */
|
||||
|
||||
int search_config_file(char *filename, char *keyword, char *value);
|
||||
int addLeased(u_int32_t yiaddr, u_int8_t chaddr[16]);
|
||||
int check_if_already_leased(u_int32_t yiaddr);
|
||||
int get_multiple_entries(char *hay, char *needle, char *tmp1, char *tmp2, char *tmp3);
|
||||
|
58
nettel.c
Normal file
58
nettel.c
Normal file
@@ -0,0 +1,58 @@
|
||||
/* nettel.c -- NETtel specific functions for the DHCP server */
|
||||
#ifdef CONFIG_NETtel
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include "dhcpd.h"
|
||||
|
||||
|
||||
int commitChanges() {
|
||||
char value[5];
|
||||
pid_t pid;
|
||||
FILE *in;
|
||||
|
||||
/* get the pid of flatfsd */
|
||||
if ((in = fopen("/var/log/flatfsd.pid", "r")) == NULL)
|
||||
return -1;
|
||||
|
||||
if(fread(&pid, sizeof(pid_t), 1, in) <= 0) {
|
||||
fclose(in);
|
||||
return -1;
|
||||
}
|
||||
fclose(in);
|
||||
|
||||
if((kill(pid, 10)) == -1)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int route_add_host(int type) {
|
||||
pid_t pid;
|
||||
char *argv[16];
|
||||
int s, argc = 0;
|
||||
|
||||
/* route add -host 255.255.255.255 eth0 */
|
||||
if((pid = vfork()) == 0) { /* child */
|
||||
argv[argc++] = "/bin/route";
|
||||
if(type == ADD)
|
||||
argv[argc++] = "add";
|
||||
else if(type == DEL)
|
||||
argv[argc++] = "del";
|
||||
argv[argc++] = "-host";
|
||||
argv[argc++] = "255.255.255.255";
|
||||
argv[argc++] = "eth0";
|
||||
argv[argc] = NULL;
|
||||
execvp("/bin/route", argv);
|
||||
exit(0);
|
||||
} else if (pid > 0) {
|
||||
waitpid(pid, &s, 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
5
nettel.h
Normal file
5
nettel.h
Normal file
@@ -0,0 +1,5 @@
|
||||
/* nettel.h */
|
||||
|
||||
int commitChanges();
|
||||
int route_add_host(int type);
|
||||
|
102
options.c
Normal file
102
options.c
Normal file
@@ -0,0 +1,102 @@
|
||||
/* options.c -- DHCP server option packet tools */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
/* add new option data to the options field terminating
|
||||
* with an 0xff */
|
||||
int addOption(unsigned char *optionptr, unsigned char code,
|
||||
char datalength, char *data) {
|
||||
endOption(&optionptr);
|
||||
optionptr[0] = code;
|
||||
if(code == 0xff)
|
||||
return 0;
|
||||
optionptr++;
|
||||
optionptr[0] = datalength;
|
||||
optionptr++;
|
||||
memcpy(optionptr, data, datalength);
|
||||
optionptr += datalength;
|
||||
optionptr[0] = 0xff;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int add_multiple_option(unsigned char *optionptr, unsigned char code,
|
||||
char datalength, char *data1, char *data2, char *data3) {
|
||||
endOption(&optionptr);
|
||||
optionptr[0] = code;
|
||||
if(code == 0xff)
|
||||
return 0;
|
||||
optionptr++;
|
||||
optionptr[0] = datalength;
|
||||
optionptr++;
|
||||
|
||||
if(data1 != NULL) {
|
||||
memcpy(optionptr, data1, 0x04);
|
||||
optionptr += 0x04;
|
||||
if(data2 != NULL) {
|
||||
memcpy(optionptr, data2, 0x04);
|
||||
optionptr += 0x04;
|
||||
if(data3 != NULL) {
|
||||
memcpy(optionptr, data3, 0x04);
|
||||
optionptr += 0x04;
|
||||
}
|
||||
}
|
||||
}
|
||||
optionptr[0] = 0xff;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int addOptionMulti(unsigned char *optionptr, unsigned char code,
|
||||
char datalength, char *data,int mul) {
|
||||
int i;
|
||||
|
||||
endOption(&optionptr);
|
||||
optionptr[0] = code;
|
||||
if(code == 0xff)
|
||||
return 0;
|
||||
optionptr++;
|
||||
optionptr[0] = (datalength * mul);
|
||||
optionptr++;
|
||||
for (i=0;i<mul;i++) {
|
||||
memcpy(optionptr, data, datalength);
|
||||
optionptr += datalength;
|
||||
}
|
||||
optionptr[0] = 0xff;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* update the option pointer to point to where the 0xff is */
|
||||
int endOption(unsigned char **optionptr) {
|
||||
unsigned char *tmpptr = *optionptr;
|
||||
|
||||
while(tmpptr[0] != 0xff) {
|
||||
if(tmpptr[0] == 0x00)
|
||||
continue;
|
||||
tmpptr++;
|
||||
tmpptr += tmpptr[0];
|
||||
tmpptr++;
|
||||
}
|
||||
*optionptr = tmpptr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
unsigned char *getOption(unsigned char *options, int option_val) {
|
||||
while(options[0] != 0xff) {
|
||||
if(options[0] == 0) {
|
||||
options++;
|
||||
continue;
|
||||
}
|
||||
if(options[0] == 0xff)
|
||||
return NULL;
|
||||
if(options[0] == option_val)
|
||||
return options+2;
|
||||
options++;
|
||||
options += options[0];
|
||||
options++;
|
||||
}
|
||||
return NULL; /* never executed */
|
||||
}
|
10
options.h
Normal file
10
options.h
Normal file
@@ -0,0 +1,10 @@
|
||||
/* options.h */
|
||||
|
||||
unsigned char *getOption(unsigned char *options, int option_val);
|
||||
int endOption(unsigned char **optionptr);
|
||||
int addOption(unsigned char *optionptr, unsigned char code, char datalength, char *data);
|
||||
int addOptionMulti(unsigned char *optionptr, unsigned char code,
|
||||
char datalength, char *data,int mul);
|
||||
int add_multiple_option(unsigned char *optionptr, unsigned char code,
|
||||
char datalength, char *data1, char *data2, char *data3);
|
||||
|
30
samples/README
Normal file
30
samples/README
Normal file
@@ -0,0 +1,30 @@
|
||||
By default, on generic Linux systems, these files should be located in
|
||||
/etc/ directory. You can change this by editing the #define in dhcpd.c
|
||||
DHCPD_*_FILE
|
||||
|
||||
|
||||
|
||||
dhcpd.conf
|
||||
----------
|
||||
|
||||
Sample DHCPD config file where the following entries are permitted:
|
||||
|
||||
subnet x.x.x.x
|
||||
wins x.x.x.x
|
||||
gateway x.x.x.x
|
||||
dns x.x.x.x
|
||||
|
||||
|
||||
dhcpd.iplist
|
||||
------------
|
||||
|
||||
sample DHCPD IP list pool file (must be in binary format).
|
||||
This sample file has the following addresses in the pool (and
|
||||
was created with the 'makeiplist' tool):
|
||||
|
||||
192.168.111.33
|
||||
192.168.111.34
|
||||
192.168.111.35
|
||||
192.168.111.36
|
||||
|
||||
|
4
samples/dhcpd.conf
Normal file
4
samples/dhcpd.conf
Normal file
@@ -0,0 +1,4 @@
|
||||
subnet 255.255.255.0
|
||||
router 192.168.111.1
|
||||
dns 192.168.111.2
|
||||
wins 192.168.111.3
|
1
samples/dhcpd.iplist
Normal file
1
samples/dhcpd.iplist
Normal file
@@ -0,0 +1 @@
|
||||
<EFBFBD><EFBFBD>o!<21><>o"<22><>o#<23><>o$
|
75
socket.c
Normal file
75
socket.c
Normal file
@@ -0,0 +1,75 @@
|
||||
/* socket.c -- DHCP server client/server socket creation */
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/stat.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
/*
|
||||
#ifndef EMBED
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
*/
|
||||
|
||||
int serverSocket(short listen_port) {
|
||||
int server_socket;
|
||||
struct sockaddr_in server;
|
||||
int n = 1;
|
||||
|
||||
server_socket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if(server_socket == -1)
|
||||
return -1;
|
||||
|
||||
bzero(&server, sizeof(server));
|
||||
server.sin_family = AF_INET;
|
||||
server.sin_port = htons(listen_port);
|
||||
server.sin_addr.s_addr = INADDR_ANY;
|
||||
|
||||
if(setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, (char *) &n, sizeof(n)) == -1)
|
||||
return -1;
|
||||
if(bind(server_socket, (struct sockaddr *)&server, sizeof(struct sockaddr)) == -1)
|
||||
return -1;
|
||||
|
||||
return server_socket;
|
||||
}
|
||||
|
||||
|
||||
int clientSocket(short send_from_port, short send_to_port) {
|
||||
int n = 1;
|
||||
int client_socket;
|
||||
struct sockaddr_in client;
|
||||
|
||||
client_socket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if(client_socket == -1)
|
||||
return -1;
|
||||
|
||||
if (setsockopt(client_socket, SOL_SOCKET, SO_REUSEADDR, (char *) &n, sizeof(n)) == -1)
|
||||
return -1;
|
||||
|
||||
setsockopt(client_socket, SOL_SOCKET, SO_BROADCAST, (char *) &n, sizeof(n));
|
||||
bzero(&client, sizeof(client));
|
||||
client.sin_family = AF_INET;
|
||||
client.sin_port = htons(send_from_port);
|
||||
client.sin_addr.s_addr = INADDR_ANY;
|
||||
|
||||
if(bind(client_socket,(struct sockaddr *)&client, sizeof(struct sockaddr))==-1)
|
||||
return -1;
|
||||
|
||||
bzero(&client, sizeof(client));
|
||||
client.sin_family = AF_INET;
|
||||
client.sin_port = htons(send_to_port);
|
||||
client.sin_addr.s_addr = INADDR_BROADCAST;
|
||||
|
||||
if(connect(client_socket, (struct sockaddr *)&client, sizeof(struct sockaddr)) == -1)
|
||||
return -1;
|
||||
|
||||
return client_socket;
|
||||
}
|
Reference in New Issue
Block a user