# configure.ps1 -- the per-pod install step, called by postinstall.bat (elevated). # On THIS machine it: finds the NIC + its static IP (the bay IP), derives the # DOSBox game IP = bayIP + 100, binds DOSBox's pcap to the NIC, renders the # net_*.conf templates, and stamps the WATTCP.CFG my_ip. Air-gapped, static, # <=32 pods. See ../DEPLOYMENT-PLAN.md. param([Parameter(Mandatory = $true)][string]$Root) $ErrorActionPreference = 'Stop' function Log($m) { Write-Host "[configure] $m" } # --- prefix length -> dotted netmask ------------------------------------- function PrefixToMask([int]$p) { $bits = ('1' * $p).PadRight(32, '0') $o = 0..3 | ForEach-Object { [Convert]::ToInt32($bits.Substring($_ * 8, 8), 2) } return ($o -join '.') } # --- 1. the pod's NIC + bay IP (the one real static IPv4) ---------------- $ip = Get-NetIPAddress -AddressFamily IPv4 | Where-Object { $_.IPAddress -notlike '127.*' -and $_.IPAddress -notlike '169.254.*' } | Sort-Object -Property SkipAsSource, InterfaceMetric | Select-Object -First 1 if (-not $ip) { throw "no usable static IPv4 found on any adapter" } $bayIp = $ip.IPAddress $ifIndex = $ip.InterfaceIndex $adapter = Get-NetAdapter -InterfaceIndex $ifIndex $guid = $adapter.InterfaceGuid.Trim('{', '}') $mask = PrefixToMask $ip.PrefixLength Log "bay IP $bayIp/$($ip.PrefixLength) on '$($adapter.Name)' guid $guid" # --- 2. realnic fragment. Must be a CONTIGUOUS substring of the pcap device # name (\Device\NPF_{GUID}, hyphens included), so take it from ONE # hyphen-delimited GUID block -- letter-leading (DOSBox reads a leading # DIGIT as an interface index) and length >= 6 for uniqueness. Longest. -- $realnic = $null foreach ($blk in ($guid -split '-')) { $mm = [regex]::Match($blk, '[A-Fa-f][0-9A-Fa-f]{5,}') if ($mm.Success -and (-not $realnic -or $mm.Value.Length -gt $realnic.Length)) { $realnic = $mm.Value } } if (-not $realnic) { throw "no letter-leading >=6-char realnic fragment in any block of GUID $guid" } Log "realnic fragment = $realnic" # --- 3. game IP = bay IP + 100 on the last octet ------------------------- $o = $bayIp.Split('.') $last = [int]$o[3] + 100 if ($last -gt 254) { throw "bay last octet $($o[3]) + 100 = $last overflows 254; keep bays <= .100" } $gameIp = "$($o[0]).$($o[1]).$($o[2]).$last" Log "game IP = $gameIp (bay + 100)" # --- 4. stable locally-administered MAC from the game IP ------------------ $mac = "02:00:{0:X2}:{1:X2}:{2:X2}:{3:X2}" -f [int]$o[0], [int]$o[1], [int]$o[2], $last Log "macaddr = $mac" # --- 5. gateway/nameserver: the host's real gateway if set, else the host # itself (always up + on-subnet -> WATTCP's boot ARP resolves; never # actually routed, the mesh is same-subnet L2) ----------------------- $gw = $null try { $gw = (Get-NetIPConfiguration -InterfaceIndex $ifIndex).IPv4DefaultGateway.NextHop } catch { } if (-not $gw) { $gw = $bayIp } Log "gateway/nameserver = $gw" # --- 6. render the conf templates (@@ROOT@@/@@REALNIC@@/@@MACADDR@@) ------ $tokens = @{ '@@ROOT@@' = $Root; '@@REALNIC@@' = $realnic; '@@MACADDR@@' = $mac } $tmpls = Get-ChildItem -Path $Root -Filter '*.conf.tmpl' -ErrorAction SilentlyContinue if (-not $tmpls) { throw "no *.conf.tmpl found in $Root" } foreach ($t in $tmpls) { $text = Get-Content -Path $t.FullName -Raw foreach ($k in $tokens.Keys) { $text = $text.Replace($k, $tokens[$k]) } $out = Join-Path $Root ($t.Name -replace '\.tmpl$', '') Set-Content -Path $out -Value $text -Encoding Ascii -NoNewline Log "rendered $($t.Name -replace '\.tmpl$','')" } # --- 7. stamp WATTCP.CFG my_ip = game IP (all copies the game may read) --- $wattcp = @( (Join-Path $Root 'ALPHA_1\REL410\BT\WATTCP.CFG'), (Join-Path $Root 'ALPHA_1\REL410\RP\WATTCP.CFG'), (Join-Path $Root 'ALPHA_1\VGL_LABS\THISPOD\WATTCP.CFG') ) $lines = @("my_ip = $gameIp", "netmask = $mask", "nameserver = $gw", "gateway = $gw") $stamped = 0 foreach ($w in $wattcp) { if (Test-Path $w) { Set-Content -Path $w -Value $lines -Encoding Ascii; $stamped++; Log "stamped $w" } } if ($stamped -eq 0) { throw "no WATTCP.CFG found under $Root\ALPHA_1" } Log "OK: bay=$bayIp game=$gameIp mac=$mac realnic=$realnic ($stamped WATTCP.CFG)"