From 09ea945c3908fd42e90eb64c194d9af11d174206 Mon Sep 17 00:00:00 2001 From: Kristian Lyngstol Date: Tue, 12 Apr 2016 18:01:32 +0200 Subject: Actual initial import Fetched from tgmanage. --- clients/dhcptail.pl | 59 + clients/ping.pl | 100 + clients/snmpfetchng.pl | 141 + fap/README.md | 37 + fap/database/README.md | 63 + fap/dhcpd/DHCP_protocol_breakdown.txt | 18 + fap/dhcpd/module_craft_option.py | 79 + fap/dhcpd/module_lease.py | 174 + fap/dhcpd/server_dhcp.py | 360 ++ fap/dhcpd/terminal.log | 146 + fap/httpd/# DEPRECATED/server_http.py | 146 + fap/httpd/# DEPRECATED/terminal.log | 14 + fap/httpd/README.md | 26 + fap/httpd/files/.gitignore | 3 + .../create_queries.php | 55 + .../ipcalc_functions.php | 134 + .../# create_queries - DEPRECATED/patchlist.txt | 142 + .../# create_queries - DEPRECATED/switches.txt | 142 + fap/httpd/httpd_root/.gitignore | 0 fap/httpd/httpd_root/.htaccess | 3 + fap/httpd/httpd_root/ex2200.template | 288 + fap/httpd/httpd_root/ex2200_secure.template | 312 + fap/httpd/httpd_root/pg_connect.php | 6 + fap/httpd/httpd_root/x.php | 67 + fap/logs/httpd.log | 667 ++ fap/proof_of_concepts/distro_during_testing.config | 355 ++ fap/proof_of_concepts/tg15-tech82-poc1.tar.gz | Bin 0 -> 4691 bytes fap/tools_temp/get_info.php | 48 + include/config.pm.dist | 109 + include/nms.pm | 186 + include/nms/snmp.pm | 91 + include/nms/util.pm | 141 + include/nms/web.pm | 112 + misc/apache2.conf | 56 + misc/varnish.vcl | 55 + tools/add_switches.txt.pl | 17 + tools/deplist.sh | 22 + tools/get_mibs.sh | 15 + web/api/API.rst | 131 + web/api/public/dhcp | 20 + web/api/public/dhcp-summary | 16 + web/api/public/location | 44 + web/api/public/ping | 37 + web/api/public/switch-state | 97 + web/api/public/switches | 36 + web/api/read/comments | 15 + web/api/read/snmp | 30 + web/api/read/switches-management | 30 + web/api/write/comment-add | 24 + web/api/write/comment-change | 25 + web/api/write/switch-add | 92 + web/api/write/switch-update | 123 + web/css/bootstrap-theme.css | 476 ++ web/css/bootstrap-theme.css.map | 1 + web/css/bootstrap-theme.min.css | 5 + web/css/bootstrap.css | 6584 ++++++++++++++++++++ web/css/bootstrap.css.map | 1 + web/css/bootstrap.min.css | 5 + web/css/jquery.datetimepicker.css | 568 ++ web/css/navbar-static-top.css | 4 + web/fonts/glyphicons-halflings-regular.eot | Bin 0 -> 20127 bytes web/fonts/glyphicons-halflings-regular.svg | 288 + web/fonts/glyphicons-halflings-regular.ttf | Bin 0 -> 45404 bytes web/fonts/glyphicons-halflings-regular.woff | Bin 0 -> 23424 bytes web/fonts/glyphicons-halflings-regular.woff2 | Bin 0 -> 18028 bytes web/img/tg15-salkart-clean-big.png | Bin 0 -> 84362 bytes web/img/tg15-salkart-full.png | Bin 0 -> 167427 bytes web/img/tg15-salkart.png | Bin 0 -> 141073 bytes web/img/tg16-salkart-clean-big.png | Bin 0 -> 293835 bytes web/img/tg16-salkart-full.png | Bin 0 -> 575014 bytes web/index.html | 337 + web/js/bootstrap.js | 2317 +++++++ web/js/bootstrap.min.js | 7 + web/js/jquery.datetimepicker.full.js | 3073 +++++++++ web/js/jquery.min.js | 4 + web/js/nms-color-util.js | 93 + web/js/nms-data.js | 259 + web/js/nms-info-box.js | 1177 ++++ web/js/nms-map-handlers.js | 490 ++ web/js/nms-map.js | 590 ++ web/js/nms.js | 792 +++ web/js/npm.js | 13 + 82 files changed, 22193 insertions(+) create mode 100755 clients/dhcptail.pl create mode 100755 clients/ping.pl create mode 100755 clients/snmpfetchng.pl create mode 100755 fap/README.md create mode 100755 fap/database/README.md create mode 100755 fap/dhcpd/DHCP_protocol_breakdown.txt create mode 100755 fap/dhcpd/module_craft_option.py create mode 100755 fap/dhcpd/module_lease.py create mode 100755 fap/dhcpd/server_dhcp.py create mode 100755 fap/dhcpd/terminal.log create mode 100755 fap/httpd/# DEPRECATED/server_http.py create mode 100755 fap/httpd/# DEPRECATED/terminal.log create mode 100755 fap/httpd/README.md create mode 100755 fap/httpd/files/.gitignore create mode 100644 fap/httpd/httpd_root/# create_queries - DEPRECATED/create_queries.php create mode 100644 fap/httpd/httpd_root/# create_queries - DEPRECATED/ipcalc_functions.php create mode 100644 fap/httpd/httpd_root/# create_queries - DEPRECATED/patchlist.txt create mode 100644 fap/httpd/httpd_root/# create_queries - DEPRECATED/switches.txt create mode 100644 fap/httpd/httpd_root/.gitignore create mode 100755 fap/httpd/httpd_root/.htaccess create mode 100755 fap/httpd/httpd_root/ex2200.template create mode 100755 fap/httpd/httpd_root/ex2200_secure.template create mode 100644 fap/httpd/httpd_root/pg_connect.php create mode 100755 fap/httpd/httpd_root/x.php create mode 100644 fap/logs/httpd.log create mode 100755 fap/proof_of_concepts/distro_during_testing.config create mode 100755 fap/proof_of_concepts/tg15-tech82-poc1.tar.gz create mode 100644 fap/tools_temp/get_info.php create mode 100755 include/config.pm.dist create mode 100755 include/nms.pm create mode 100644 include/nms/snmp.pm create mode 100644 include/nms/util.pm create mode 100755 include/nms/web.pm create mode 100644 misc/apache2.conf create mode 100644 misc/varnish.vcl create mode 100755 tools/add_switches.txt.pl create mode 100755 tools/deplist.sh create mode 100755 tools/get_mibs.sh create mode 100644 web/api/API.rst create mode 100755 web/api/public/dhcp create mode 100755 web/api/public/dhcp-summary create mode 100755 web/api/public/location create mode 100755 web/api/public/ping create mode 100755 web/api/public/switch-state create mode 100755 web/api/public/switches create mode 100755 web/api/read/comments create mode 100755 web/api/read/snmp create mode 100755 web/api/read/switches-management create mode 100755 web/api/write/comment-add create mode 100755 web/api/write/comment-change create mode 100755 web/api/write/switch-add create mode 100755 web/api/write/switch-update create mode 100644 web/css/bootstrap-theme.css create mode 100644 web/css/bootstrap-theme.css.map create mode 100644 web/css/bootstrap-theme.min.css create mode 100644 web/css/bootstrap.css create mode 100644 web/css/bootstrap.css.map create mode 100644 web/css/bootstrap.min.css create mode 100644 web/css/jquery.datetimepicker.css create mode 100644 web/css/navbar-static-top.css create mode 100644 web/fonts/glyphicons-halflings-regular.eot create mode 100644 web/fonts/glyphicons-halflings-regular.svg create mode 100644 web/fonts/glyphicons-halflings-regular.ttf create mode 100644 web/fonts/glyphicons-halflings-regular.woff create mode 100644 web/fonts/glyphicons-halflings-regular.woff2 create mode 100644 web/img/tg15-salkart-clean-big.png create mode 100644 web/img/tg15-salkart-full.png create mode 100644 web/img/tg15-salkart.png create mode 100644 web/img/tg16-salkart-clean-big.png create mode 100644 web/img/tg16-salkart-full.png create mode 100644 web/index.html create mode 100644 web/js/bootstrap.js create mode 100644 web/js/bootstrap.min.js create mode 100644 web/js/jquery.datetimepicker.full.js create mode 100644 web/js/jquery.min.js create mode 100644 web/js/nms-color-util.js create mode 100644 web/js/nms-data.js create mode 100644 web/js/nms-info-box.js create mode 100644 web/js/nms-map-handlers.js create mode 100644 web/js/nms-map.js create mode 100644 web/js/nms.js create mode 100644 web/js/npm.js diff --git a/clients/dhcptail.pl b/clients/dhcptail.pl new file mode 100755 index 0000000..9c2111f --- /dev/null +++ b/clients/dhcptail.pl @@ -0,0 +1,59 @@ +#! /usr/bin/perl +use DBI; +use POSIX; +use lib '../include'; +use nms; +use strict; +use Data::Dumper; +use warnings; + +BEGIN { + require "../include/config.pm"; + eval { + require "../include/config.local.pm"; + }; +} + +my $year = $nms::config::tgname; +$year =~ s/tg/20/; # hihi + +my %months = ( + Jan => 1, + Feb => 2, + Mar => 3, + Apr => 4, + May => 5, + Jun => 6, + Jul => 7, + Aug => 8, + Sep => 9, + Oct => 10, + Nov => 11, + Dec => 12 +); + +my $realtime = 0; +my ($dbh, $q,$check); +$dbh = nms::db_connect(); +$q = $dbh->prepare("INSERT INTO dhcp (switch,time,ip,mac) VALUES((SELECT switch FROM switches WHERE ?::inet << subnet4 ORDER BY sysname LIMIT 1),?,?,?)"); +$check = $dbh->prepare("SELECT max(time)::timestamp - ?::timestamp < '0s'::interval as doit FROM dhcp;"); + +open(SYSLOG, "tail -n 9999999 -F /var/log/syslog |") or die "Unable to tail syslog: $!"; +while () { + /(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+(\d+)\s+(\d+:\d+:\d+).*DHCPACK on (\d+\.\d+\.\d+\.\d+) to (\S+) / or next; + my $date = $year . "-" . $months{$1} . "-" . $2 . " " . $3 . " Europe/Oslo"; + my $machine = $5; + my $via = $6; + $check->execute($date); + $dbh->commit; + my $cond = $check->fetchrow_hashref(); + if (!defined($cond) or !defined($cond->{'doit'}) or $cond->{'doit'} eq '1') { + if ($realtime != 1) { + $realtime = 1; + print "real time achieved...\n"; + } + $q->execute($4,$date,$4,$machine); + $dbh->commit; + } +} +close SYSLOG; diff --git a/clients/ping.pl b/clients/ping.pl new file mode 100755 index 0000000..d945917 --- /dev/null +++ b/clients/ping.pl @@ -0,0 +1,100 @@ +#! /usr/bin/perl +use DBI; +use POSIX; +use Time::HiRes; +use Net::Oping; +use strict; +use warnings; +use Data::Dumper; + +use lib '../include'; +use nms; + +$|++; +my $dbh = nms::db_connect(); +$dbh->{AutoCommit} = 0; +$dbh->{RaiseError} = 1; + +my $q = $dbh->prepare("SELECT switch,host(mgmt_v4_addr) as ip,host(mgmt_v6_addr) as secondary_ip FROM switches WHERE mgmt_v4_addr is not null ORDER BY random()"); +my $lq = $dbh->prepare("SELECT linknet,addr1,addr2 FROM linknets WHERE addr1 is not null and addr2 is not null"); + +while (1) { + # ping loopbacks + my $ping = Net::Oping->new; + $ping->timeout(0.3); + + $q->execute; + my %ip_to_switch = (); + my %secondary_ip_to_switch = (); + while (my $ref = $q->fetchrow_hashref) { + my $switch = $ref->{'switch'}; + + my $ip = $ref->{'ip'}; + $ping->host_add($ip); + $ip_to_switch{$ip} = $switch; + + my $secondary_ip = $ref->{'secondary_ip'}; + if (defined($secondary_ip)) { + $ping->host_add($secondary_ip); + $secondary_ip_to_switch{$secondary_ip} = $switch; + } + } + my $result = $ping->ping(); + my %dropped = %{$ping->get_dropped()}; + die $ping->get_error if (!defined($result)); + + $dbh->do('COPY ping (switch, latency_ms) FROM STDIN'); # date is implicitly now. + my $drops = 0; + while (my ($ip, $latency) = each %$result) { + my $switch = $ip_to_switch{$ip}; + next if (!defined($switch)); + + if (!defined($latency)) { + $drops += $dropped{$ip}; + } + $latency //= "\\N"; + $dbh->pg_putcopydata("$switch\t$latency\n"); + } + if ($drops > 0) { + print "$drops "; + } + $dbh->pg_putcopyend(); + + $dbh->do('COPY ping_secondary_ip (switch, latency_ms) FROM STDIN'); # date is implicitly now. + while (my ($ip, $latency) = each %$result) { + my $switch = $secondary_ip_to_switch{$ip}; + next if (!defined($switch)); + + $latency //= "\\N"; + $dbh->pg_putcopydata("$switch\t$latency\n"); + } + $dbh->pg_putcopyend(); + + $dbh->commit; + # ping linknets + $ping = Net::Oping->new; + $ping->timeout(0.3); + + $lq->execute; + my @linknets = (); + while (my $ref = $lq->fetchrow_hashref) { + push @linknets, $ref; + $ping->host_add($ref->{'addr1'}); + $ping->host_add($ref->{'addr2'}); + } + if (@linknets) { + $result = $ping->ping(); + die $ping->get_error if (!defined($result)); + + $dbh->do('COPY linknet_ping (linknet, latency1_ms, latency2_ms) FROM STDIN'); # date is implicitly now. + for my $linknet (@linknets) { + my $id = $linknet->{'linknet'}; + my $latency1 = $result->{$linknet->{'addr1'}} // '\N'; + my $latency2 = $result->{$linknet->{'addr2'}} // '\N'; + $dbh->pg_putcopydata("$id\t$latency1\t$latency2\n"); + } + $dbh->pg_putcopyend(); + } + $dbh->commit; +} + diff --git a/clients/snmpfetchng.pl b/clients/snmpfetchng.pl new file mode 100755 index 0000000..2f5e785 --- /dev/null +++ b/clients/snmpfetchng.pl @@ -0,0 +1,141 @@ +#!/usr/bin/perl +use strict; +use warnings; +use DBI; +use POSIX; +#use Time::HiRes qw(time); +use SNMP; +use Data::Dumper; +use lib '../include'; +use nms; + +SNMP::initMib(); +SNMP::addMibDirs("/srv/tgmanage/mibs/StandardMibs"); +SNMP::addMibDirs("/srv/tgmanage/mibs/JuniperMibs"); +SNMP::addMibDirs("/srv/tgmanage/mibs"); +SNMP::loadModules('ALL'); + +our $dbh = nms::db_connect(); +$dbh->{AutoCommit} = 0; +$dbh->{RaiseError} = 1; + +my $qualification = <<"EOF"; +(last_updated IS NULL OR now() - last_updated > poll_frequency) +AND (locked='f' OR now() - last_updated > '15 minutes'::interval) +AND mgmt_v4_addr is not null +EOF + +# Borrowed from snmpfetch.pl +our $qswitch = $dbh->prepare(<<"EOF") +SELECT + sysname,switch,host(mgmt_v4_addr) as ip,community, + DATE_TRUNC('second', now() - last_updated - poll_frequency) AS overdue +FROM + switches +WHERE +$qualification +ORDER BY + overdue DESC +LIMIT ? +EOF + or die "Couldn't prepare qswitch"; +our $qlock = $dbh->prepare("UPDATE switches SET locked='t', last_updated=now() WHERE switch=?") + or die "Couldn't prepare qlock"; +our $qunlock = $dbh->prepare("UPDATE switches SET locked='f', last_updated=now() WHERE switch=?") + or die "Couldn't prepare qunlock"; +my @switches = (); + +my $sth = $dbh->prepare("INSERT INTO snmp (switch,data) VALUES((select switch from switches where sysname=?), ?)"); + +sub mylog +{ + my $msg = shift; + my $time = POSIX::ctime(time); + $time =~ s/\n.*$//; + printf STDERR "[%s] %s\n", $time, $msg; +} + +sub populate_switches +{ + @switches = (); + my $limit = $nms::config::snmp_max; + $qswitch->execute($limit) + or die "Couldn't get switch"; + $dbh->commit; + while (my $ref = $qswitch->fetchrow_hashref()) { + push @switches, { + 'sysname' => $ref->{'sysname'}, + 'id' => $ref->{'switch'}, + 'mgtip' => $ref->{'ip'}, + 'community' => $ref->{'community'} + }; + } +} + +sub inner_loop +{ + populate_switches(); + my $poll_todo = ""; + for my $refswitch (@switches) { + my %switch = %{$refswitch}; + $poll_todo .= "$switch{'sysname'} "; + + $switch{'start'} = time; + $qlock->execute($switch{'id'}) + or die "Couldn't lock switch"; + $dbh->commit; + my $s = SNMP::Session->new(DestHost => $switch{'mgtip'}, + Community => $switch{'community'}, + UseEnums => 1, + Version => '2'); + my $ret = $s->bulkwalk(0, 10, @nms::config::snmp_objects, sub{ callback(\%switch, @_); }); + if (!defined($ret)) { + mylog("Fudge: ". $s->{'ErrorStr'}); + } + } + mylog( "Polling " . @switches . " switches: $poll_todo"); + SNMP::MainLoop(10); +} + +sub callback{ + my @top = $_[1]; + my %switch = %{$_[0]}; + my %tree; + my %ttop; + my %nics; + my @nicids; + + for my $ret (@top) { + for my $var (@{$ret}) { + for my $inner (@{$var}) { + my ($tag,$type,$name,$iid, $val) = ( $inner->tag ,$inner->type , $inner->name, $inner->iid, $inner->val); + if ($tag eq "ifPhysAddress") { + next; + } + $tree{$iid}{$tag} = $val; + if ($tag eq "ifIndex") { + push @nicids, $iid; + } + } + } + } + + my %tree2; + for my $nic (@nicids) { + $tree2{'ports'}{$tree{$nic}{'ifName'}} = $tree{$nic}; + delete $tree{$nic}; + } + for my $iid (keys %tree) { + for my $key (keys %{$tree{$iid}}) { + $tree2{'misc'}{$key}{$iid} = $tree{$iid}{$key}; + } + } + $sth->execute($switch{'sysname'}, JSON::XS::encode_json(\%tree2)); + $qunlock->execute($switch{'id'}) + or die "Couldn't unlock switch"; + $dbh->commit; + mylog( "Polled $switch{'sysname'} in " . (time - $switch{'start'}) . "s."); +} +while (1) { + inner_loop(); +} diff --git a/fap/README.md b/fap/README.md new file mode 100755 index 0000000..c8278f5 --- /dev/null +++ b/fap/README.md @@ -0,0 +1,37 @@ +# FAP - Fast and Agile Provisioning + +Tools (DHCP daemon + HTTP daemon + DB) for managing provisioning towards a large number of factory default Juniper switches (EX2200) using ZTP (Zero Touch Protocol) over DHCP relays. + +The project is built with Python (>3.4.0) and PostgreSQL (>9.3.5). + +Licensed under the GNU GPL, version 2. See the included COPYING file. + + + +## Usage +Launch the python scripts for fap from tgmanage directory. + + apt-get install apache2 php5 python3 python3-psycopg2 php5-pgsql + a2enmod cgi + a2enmod rewrite + + + +### HTTPD + j@lappie:~/git/tgmanage$ sudo python3 fap/httpd/server_http.py + +Example: httpd/terminal.log + + +### DHCPD + j@lappie:~/git/tgmanage$ sudo python3 fap/dhcpd/server_dhcp.py + +Example: dhcpd/terminal.log + + +# TODO +* DONE: Support for IPv6 management +* Process multiple HTTP request simultaneously +* Support for only pushing JunOS image to switch - no config (for backup switches) +* Try/catch on whole ethernet frame in DHCPD +* Timestamps on each line in log both from DHCPD and HTTPD diff --git a/fap/database/README.md b/fap/database/README.md new file mode 100755 index 0000000..3d014d3 --- /dev/null +++ b/fap/database/README.md @@ -0,0 +1,63 @@ +# Database layout + +PostgreSQL + +**Tables** +``` +bootstrap-> \dt + List of relations + Schema | Name | Type | Owner +--------+----------+-------+----------- + public | switches | table | bootstrap +``` + + +**Table structure** +``` +fap=> \d switches + Table "public.switches" + Column | Type | Modifiers +-------------------+------------------------+------------------------------------------------------- + id | integer | not null default nextval('switches_id_seq'::regclass) + hostname | character varying(20) | + distro_name | character varying(100) | + distro_phy_port | character varying(100) | + mgmt_v4_addr | character varying(15) | + mgmt_v4_cidr | smallint | + mgmt_v4_gw | character varying(15) | + mgmt_v6_cidr | smallint | + mgmt_v6_addr | character varying(35) | + mgmt_v6_gw | character varying(35) | + mgmt_vlan | smallint | + last_config_fetch | integer | + current_mac | character varying(17) | + model | character varying(20) | + traffic_vlan | integer | +``` + + +**Sample content in DB** +``` +fap=> select * from switches where [...] order by id desc; + id | hostname | distro_name | distro_phy_port | mgmt_v4_addr | mgmt_v4_cidr | mgmt_v4_gw | mgmt_v6_cidr | mgmt_v6_addr | mgmt_v6_gw | mgmt_vlan | last_config_fetch | current_mac | model | traffic_vlan +-----+--------------------+----------------+-----------------+-----------------+--------------+-----------------+--------------+---------------------+-------------------+-----------+-------------------+-------------------+-------+-------------- + 447 | sw1-crew | rs1.crew | ge-0/0/39 | 151.216.183.66 | 27 | 151.216.183.65 | 64 | 2a02:ed02:1832::66 | 2a02:ed02:1832::1 | 666 | | 44:f4:77:69:4d:41 | | 1701 + 442 | sw2-gamestudio | rs1.north | ge-0/0/45 | 151.216.183.230 | 27 | 151.216.183.225 | 64 | 2a02:ed02:1837::230 | 2a02:ed02:1837::1 | 666 | | 44:f4:77:69:5d:41 | | 229 + 435 | sw1-south | rs1.south | ge-0/0/45 | 151.216.183.98 | 27 | 151.216.183.97 | 64 | 2a02:ed02:1836::98 | 2a02:ed02:1836::1 | 666 | | 44:f4:77:69:49:81 | | 234 + 434 | sw8-creativia | rs1.distro6 | ge-0/0/25 | 151.216.181.155 | 26 | 151.216.181.129 | 64 | 2a02:ed02:181c::155 | 2a02:ed02:181c::1 | 666 | | 44:f4:77:69:1a:c1 | | 2008 + 420 | e83-1 | rs1.distro7 | ge-0/0/20 | 151.216.181.214 | 26 | 151.216.181.193 | 64 | 2a02:ed02:181d::214 | 2a02:ed02:181d::1 | 666 | | 44:f4:77:69:53:c1 | | 1831 + 419 | e81-2 | rs1.distro7 | ge-0/0/19 | 151.216.181.213 | 26 | 151.216.181.193 | 64 | 2a02:ed02:181d::213 | 2a02:ed02:181d::1 | 666 | | 44:f4:77:69:4b:81 | | 1812 + 418 | e81-1 | rs1.distro7 | ge-0/0/18 | 151.216.181.212 | 26 | 151.216.181.193 | 64 | 2a02:ed02:181d::212 | 2a02:ed02:181d::1 | 666 | | 44:f4:77:68:eb:c1 | | 1811 + 417 | e79-4 | rs1.distro6 | ge-0/0/17 | 151.216.181.147 | 26 | 151.216.181.129 | 64 | 2a02:ed02:181c::147 | 2a02:ed02:181c::1 | 666 | | 44:f4:77:69:02:c1 | | 1794 +``` + + +**Connect to DB from CLI** +``` +j@lappie:~/git/tgmanage$ psql -U bootstrap -d bootstrap -W +Password for user bootstrap: +psql (9.3.5) +Type "help" for help. + +bootstrap=> +``` diff --git a/fap/dhcpd/DHCP_protocol_breakdown.txt b/fap/dhcpd/DHCP_protocol_breakdown.txt new file mode 100755 index 0000000..5af2bf2 --- /dev/null +++ b/fap/dhcpd/DHCP_protocol_breakdown.txt @@ -0,0 +1,18 @@ +Length of DHCP fields in octets, and their placement in packet. +Ref: http://4.bp.blogspot.com/-IyYoFjAC4l8/UXuo16a3sII/AAAAAAAAAXQ/b6BojbYXoXg/s1600/DHCPTitle.JPG +0 OP - 1 +1 HTYPE - 1 +2 HLEN - 1 +3 HOPS - 1 +4 XID - 4 +5 SECS - 2 +6 FLAGS - 2 +7 CIADDR - 4 +8 YIADDR - 4 +9 SIADDR - 4 +10 GIADDR - 4 +11 CHADDR - 6 +12 MAGIC COOKIE - 10 +13 PADDING - 192 octets of 0's +14 MAGIC COOKIE - 4 +15 OPTIONS - variable length diff --git a/fap/dhcpd/module_craft_option.py b/fap/dhcpd/module_craft_option.py new file mode 100755 index 0000000..35e7328 --- /dev/null +++ b/fap/dhcpd/module_craft_option.py @@ -0,0 +1,79 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +''' + Created by Jonas 'j' Lindstad for The Gathering 2015 + License: GPLv3 + + Class used to craft byte hex encoded DHCP options + + NB: No direct support for suboptions. Should be possible to craft suboptions as + options, and inject them with craft_option(