#!/usr/bin/php -q
<?PHP
/* Copyright 2016, Bergware International.
 * Copyright 2016, Lime Technology
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License version 2,
 * as published by the Free Software Foundation.
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 */
?>
<?
$set = $ifname = $argv[1];
$run = $set != 'none';
$ini = parse_ini_file('/var/local/emhttp/network.ini',true); ksort($ini,SORT_NATURAL);
$cfg = '/boot/config/network.cfg';

function ifname($name) {
  global $old;
  if (!$name) return;
  for ($i=0; $i<$old['SYSNICS']; $i++) {
    $nics = $old['BONDNICS'][$i] ?: $old['BRNICS'][$i];
    if (strpos("$nics ","$name ")!==false) return $old['IFNAME'][$i];
  }
  return $name;
}

if ($run && file_exists($cfg)) {
  $old = parse_ini_string(preg_replace('/^#/m',';',file_get_contents($cfg)));
  if (isset($old['SYSNICS'])) {
    // new syntax
    $ifname = ifname($set);
  } else {
    // legacy syntax
    if ($set=='eth0') $ifname = $old['BRIDGING']=='yes' ? ($old['BRNAME'] ?: 'br0') : ($old['BONDING']=='yes' ? ($old['BONDNAME'] ?: 'bond0') : $set);
  }
}

// stop interface with existing (old) configuration
// don't execute when only interface description has changed
if ($run) exec("/etc/rc.d/rc.inet1 ".escapeshellarg("{$ifname}_stop")." >/dev/null");

if ($bonding = $ini['eth0']['BONDING']=='yes') {
  $ini['eth0']['BONDNICS'] = str_replace(',',' ',$ini['eth0']['BONDNICS']);
  $bond0 = explode(' ',trim(str_replace('eth0','',$ini['eth0']['BONDNICS'])));
// ensure additional NICs in bond are set free
  if ($run && $set=='eth0') foreach ($bond0 as $nic) {
    if (isset($old['SYSNICS'])) $nic = ifname($nic);
    if ($nic && $nic!=$ifname) exec("/etc/rc.d/rc.inet1 ".escapeshellarg("{$nic}_stop")." >/dev/null");
  }
}

if ($bridging = $ini['eth0']['BRIDGING']=='yes') {
  $ini['eth0']['BRNICS'] = str_replace(',',' ',$ini['eth0']['BRNICS']);
  $br0 = explode(' ',trim(str_replace('eth0','',$ini['eth0']['BRNICS'])));
// ensure additional NICs in bridge are set free
  if ($run && $set=='eth0' && !$bonding) foreach ($br0 as $nic) {
    if (isset($old['SYSNICS'])) $nic = ifname($nic);
    if ($nic && $nic!=$ifname) exec("/etc/rc.d/rc.inet1 ".escapeshellarg("{$nic}_start")." >/dev/null");
  }
}

// create configuration file for all available interfaces
$i = 0; $new = []; $new[] = "# Generated settings:";
foreach ($ini as $name => $port) {
  if ($bonding && in_array($name,$bond0)) continue;
  if ($bridging && in_array($name,$br0)) continue;
  $bridge = $port['BRIDGING']=='yes';
  $trunk = $port['TYPE']=='trunk';
  $j = 0; $x0 = 0;
  $iface = $bridge ? $port['BRNAME'] : ($bonding && $name=='eth0' ? $port['BONDNAME'] : $name);
  $new[] = "IFNAME[$i]=\"$iface\"";
  if ($set==$name) $ifname = $iface;
  foreach ($port as $key => $val) {
    if (preg_match('/^(TYPE|BONDING$|BRIDGING)/',$key)) continue;
    if (!$bonding && preg_match('/^(BONDING_MODE|BONDING_MIIMON|BONDNICS|BONDNAME)/',$key)) continue;
    if (!$bridge && preg_match('/^(BRSTP|BRFD|BRNICS|BRNAME)/',$key)) continue;
    list($item,$x) = explode(':',$key,2);
    if ($trunk && $x>0 && preg_match('/^(VLANID|USE_DHCP|IPADDR|NETMASK|DESCRIPTION)/',$key)) {
      if ($x0 != $x) {$x0 = $x; $j++;}
      $vlan = ",$j]";
    } else $vlan = '';
    if (!$vlan && preg_match('/^VLANID/',$key)) continue;
    $new[] = $item.(preg_match('/^(GATEWAY|DNS_SERVER|DHCP_KEEPRESOLV)/',$key)?'':'['.$i.($vlan?'':']')).$vlan."=\"$val\"";
  }
  if ($trunk) $new[] = "VLANS[$i]=\"".($j+1)."\"";
  $i++;
}
$new[] = "SYSNICS=\"$i\"";

file_put_contents($cfg,implode("\r\n",$new)."\r\n");
// start interface with updated (new) configuration
// don't execute when only interface description has changed
if ($run) exec("/etc/rc.d/rc.inet1 ".escapeshellarg("{$ifname}_start")." >/dev/null");
exit(0);
?>
