rabbit51

it's since Nov.30 2005
May.29 2014, transferred from broach

NVR510 L2TP/IPsec の暗号鍵をWireshark用にLUAスクリプトで生成する

2020-07-23 15:00:00 | NVR510
ヤマハNVR500のL2TP/IPsec VPNパケットをWiresharkで解析」で、暗号鍵をLUAスクリプトで抽出し、Wireshark暗号解読用設定ファイルを生成した。

Win10 VPN接続時のNVR500 L2TP/IPsec ISAKMP復号鍵が壊れて表示」で、ログに記録される暗号鍵は、cipher suitによって鍵の一部しか記録されない事が判明した。

NVR500の故障で「ヤマハ NVR500からNVR510へ更新

NVR510 L2TP/IPSec VPNの暗号組合せ(cipher suite)をWindows/macOS/Linux(strongSwan/xl2tpd)で接続確認」 で、NVR510のcipher suitについて確認した。

NVR510 L2TP/IPSec VPNのcipher suiteと暗号化キー値」で、NVR510のAES暗号鍵について調査したところNVR500と同等だった。
ログ記録された鍵要素から暗号鍵を再生成できるがPFS(Perfect Forward Secrecy)のDiffie-Hellman Groupによってデータが省略され再生成できない場合があった。
DH Group 1(modp768), 2(modp1024) は、省略されない。DH Group 5(modp1536), 14(modp2048)は、データの一部が省略される。ISAKMPのPhase1では、modp2048でもSKEYID_eが256bitで記録されるので鍵長不足にならない。Phase2で、AES256、PFS=onとするのであれば、Phase2のDH Groupを2(modp1024)までとする必要がある。

WiresharkでL2TP/IPsecパケットを解析するためNVR5x0のログデータからAES暗号鍵の抽出と再生成を行うLUAスクリプトを作成する。

(1)LUAスクリプトの条件
・「AES128/AES256/SHA-1/SHA-256」のcipher suitを対象
・PFS=on、DH Group 5(modp1536), 14(modp2048)でESPのAES256鍵再生成不可
・wireshark用「ikev1_decryption_table」と「esp_sa」の鍵ファイルを生成する
・prfとしてhmac-sha1とhmac-sha256計算用LUAモジュールを使用する

(2)PRF(pseudo-random function)用LUAモデュール
NVR5x0のLUAは、Version 5.1.5で「浮動小数点」を扱えない。ヤマハLUAで扱えるライブラリィ関数に注意が必要。

Egor-Skriptunoff/pure_lua_SHA2
hmac-sha1とhmac-sha256が一つのモジュールで利用できるが「数値型Double」が必須で動作しない。

mpeterv/sha ( kikito/sha1.lua )
sha1/hmac-sha1のモジュール。ヤマハLUAでは、「bit関数」を使わずbit操作処理が選択されるが、動作しない。「bit」関数を使う処理が独立ファイルで構成されているため、ヤマハLUAの「bit関数」を使用するように修正すると動作する。修正は、「sha1/bit_ops.lua」をコピーし「bit_rt_ops.lua」として「sha1/init.lua」でヤマハLUAで「sha1/bit_rt_ops.lua」が選択されるようにした。
 モジュール構成
sha1/init.lua
sha1/common.lua
sha1/pure_lua_ops.lua
sha1/bit_ops.lua
sha1/bit32_ops.lua
sha1/lua53_ops.lua
sha1/bit_rt_ops.lua

sha1/init.lua
$ diff master/src/sha1/init.lua init.lua
43a44,45
>    elseif _RT_LUA_VERSION_NUM ~= nil and _RT_LUA_VERSION_NUM >= 101 then
>       return "bit_rt_ops"
85d86
< 
89d89
< 
bit_rt_ops.lua
$ diff master/src/sha1/bit_ops.lua bit_rt_ops.lua
1c1,4
< local bit = require "bit"
---
> -- YAMAHA NVR510 LUA _VERSION 5.1 _RT_LUA_VERSION 1.08
> -- June 14,2020 
> 
> -- local bit = require "bit"
9c12
< ops.uint32_lrot = bit.rol
---
> ops.uint32_lrot = bit.brotate		-- ops.uint32_lrot = bit.rol

jqqqi/Lua-HMAC-SHA256
sha256/hmac-sha256のモジュール。ヤマハLUAでは、動作しない。「math.floor()」が使用されている。ヤマハLUAの「bit関数」を使用するように修正すると動作する。
sha256.lua
$ diff sha256-original.lua sha256.lua
10c10,11
<  
---
> 
> --[[
45c46
<  
---
>  ]]
51c52,53
< 		z = bxor1(a, b)
---
> --		z = bxor1(a, b)
> 		z = bit.bxor(a, b)
66,67c68,71
< 		z =((a + b) - bxor1(a, b)) / 2
< 		if c then z = bit32_band(z, c, ...) end
---
> --		z =((a + b) - bxor1(a, b)) / 2
> 		z =((a + b) - bit.bxor(a, b)) / 2
> --		if c then z = bit32_band(z, c, ...) end
> 		if c then z = band(z, c, ...) end
76c80
< local function bnot(x) return(-1 - x) % MOD end
---
> local function bnot(x) return bit.bnot(x % MOD) --[[ (-1 - x) % MOD]] end
78,81c82,86
< local function rshift1(a, disp)
< 	if disp < 0 then return lshift(a, - disp) end
< 	return math.floor(a % 2 ^ 32 / 2 ^ disp)
< end
---
> -- local function rshift1(a, disp)
> --	if disp < 0 then return lshift(a, - disp) end
> --	return math.floor(a % 2 ^ 32 / 2 ^ disp)
> --	return (a % 2 ^ 32 / 2 ^ disp)
> -- end
84,85c89,91
< 	if disp > 31 or disp < -31 then return 0 end
< 	return rshift1(x % MOD, disp)
---
> --	if disp > 31 or disp < -31 then return 0 end
> --	return rshift1(x % MOD, disp)
> 	return bit.bshift( x % MOD, -disp)
88,91c94,97
< local function lshift(a, disp)
< 	if disp < 0 then return rshift(a, - disp) end
< 	return(a * 2 ^ disp) % 2 ^ 32
< end
---
> -- local function lshift(a, disp)
> --	if disp < 0 then return rshift(a, - disp) end
> --	return(a * 2 ^ disp) % 2 ^ 32
> -- end
96,97c102,104
< 	local low = band(x, 2 ^ disp - 1)
< 	return rshift(x, disp) + lshift(low, 32 - disp)
---
> -- 	local low = band(x, 2 ^ disp - 1)
> -- 	return rshift(x, disp) + lshift(low, 32 - disp)
> 	return bit.brotate( x, -disp )
NVR5x0のsd1ドライブにモジュールとプログラムを配置する。
sd1構成
> show file list sd1:/lua 
2020/06/11 14:56:28 <DIR>           sha1
2020/07/06 23:45:50           26011 sha256.lua
2020/07/18 15:16:52           12493 GetNvrCryptKeys.lua
> show file list sd1:/lua/sha1 
2018/10/13 02:28:38             569 bit32_ops.lua
2018/10/13 02:28:38             553 bit_ops.lua
2018/10/13 02:28:38             427 common.lua
2020/06/25 16:20:58            6024 init.lua
2018/10/13 02:28:38             616 lua53_ops.lua
2018/10/13 02:28:38            5768 pure_lua_ops.lua
2020/06/25 16:20:28             646 bit_rt_ops.lua
プログラムから「require」でモジュールが読み込めるようにNVR5x0に「LUA_PATH』環境変数を設定する
set LUA_PATH="sd1:/lua/\?.lua;sd1:/lua/\?/init.lua;;"


(3)L2TP/IPSec接続時のcipher suiteを記録
L2TP/IPSec接続時に選択されたcipher suitが記録されないのでsyslog watchでVPN接続を監視し、「show ipsec sa gateway 2 detail」のデータから抽出しsyslogに記録するスクリプトを設定する。syslogは、「[IKEex]」で識別出来るように記録する
ckIPSecConnect.lua 
--[[("
 Jun.17 '2020 Rabbit51
 ckIPSecConnect.lua
]]
---------------------------------------------------------------
-- watching VPN Connection and get SA  info --
---------------------------------------------------------------
while(true) do
    rtn, array = rt.syslogwatch("IP Tunnel%[2%] Up")
    if rtn >0 then
        rtn2,str2 = rt.command("show ipsec sa gateway 2 detail","on")
        if rtn2 and str2 ~= nill then
            idl,idr=string.match(str2,"Local ID:%s(%d+%.%d+%.%d+%.%d+)%s+Remote ID:%s(%d+%.%d+%.%d+%.%d+)%s+Protocol")
            ike=string.match(str2, "Protocol:%sIKE.*Algorithm:%s(.*)NAT")
            esp=string.match(str2, "Protocol:%sESP.*Algorithm:%s(.*)SPI")
            if idl ~= nil then rtn3,str3 = rt.syslog("debug","[IKEex] Local ID: " .. idl) end
            if idr ~= nil then rtn4,str4 = rt.syslog("debug","[IKEex] Remote ID: " .. idr) end
            if ike ~= nil then rtn5,str5 = rt.syslog("debug","[IKEex] IKE: " .. ike) end
            if esp ~= nill then rtn6,str6 = rt.syslog("debug","[IKEex] ESP: " .. esp) end
        else
            rt7,str7 = rt.syslog("debug","IPSec connected, but no SA")
        end
    end
end
起動時に実行されるよう「schedule」設定
schedule at 10 startup * lua sd1:/lua/ckIPSecConnect.lua


(4)AES鍵抽出LUAプログラム
 GetNvrCryptKeys.lua
--[[
	Jul.16 '2020 Rabbit51
	GetNvrCryptKeys.lua
lua sd1:/lua/GetNvrCryptKeys.lua
lua sd1:/lua/GetNvrCryptKeys.lua sd1:/lua/GetNvrCryptKeyslog.txt
]]
local nvr5x0 = true
local filepath = "sd1:/lua/"
local logTmp = "GetNvrCryptKeyslog.txt"
local debugf = false

if not nvr5x0 then filepath = "" end
local tt1=0; tt2=0; tt3=0; tt4=0; tt5=0; tt6=0; tt7=0
local logData, logPPData, iip, rip, ispi, rspi, ieky, reky, dt, r, m
local cky_i, skeyid_e, modpf
local sendconf, receiveconf
logPPData=""
tt1 = os.time() -- begining

-- both modules are modified for NVR5x0 LUA
local sha1 = require "sha1" -- https://github.com/kikito/sha1.lua
local sha2 = require "sha256" -- https://github.com/jqqqi/Lua-HMAC-SHA256
  
-- hex to binary
local function hex2bin(str)
    return (str:gsub('..', function (cc)
        return string.char(tonumber(cc, 16))
    end))
end

function loadLogFile(logfile)
	local handle = io.open(logfile,"r")
	local content=handle:read("*all")
	handle:close()
	return content
end

if arg[1] ~= nil then
    logData = loadLogFile(arg[1])
else
	r,m = rt.command("delete "..filepath..logTmp)
	if r == nil then rt.syslog("info","[LUA] "..arg[0].." "..m ) end
	r,m = rt.command("show status pp 1")
	if r then
	    if m ~= nil then logPPData = m else logPPData = "" end
	else rt.syslog("info","[LUA] "..arg[0].." "..m ) end
    r,m = rt.command("show log | grep 'IKE|L2TP|ANONYMOUS01' >> "..filepath..logTmp)
    if r ~= nil then
        logData = loadLogFile(filepath..logTmp)
    else
        rt.syslog("info","[LUA] "..arg[0].." show log command error" )
		return r,m
    end
end

---- cut only last l2tp/ipsec connection data
logData = string.gsub(logData,".*%c([%d/: ]+: %[IKE%] respond ISAKMP phase to.-%[IKE%] respond IPsec phase to.*)","%1")

tt2 = os.time() -- logging
print("now picking keys data from log...\n")
-- find last IKE connection and get it the ip address and date
local pos = 1
while true do
	local pbt,pet,iipt,dtt = string.find(logData, "%[IKE%] respond IPsec phase to ([%d%.]+)%s-([%d/: ]+): ", pos)
	if pbt ~= nil then
		pb=pbt; pe=pet; iip = iipt; dt = dtt; pos = pet
	else
		break
	end
end
dt = string.gsub(dt,"[/: ]","")
print("Connection date -> "..dt)

-- SA crypt suite
-- syslog debug info. from ckIPSecConnect.lua
local ike1, ike2, ike3, esp1, esp2
for ike1t,ike2t,ike3t,esp1t,esp2t in string.gmatch(logData, "%[IKEex%] IKE: (.-), (.-), (.-bit).-%[IKEex%] ESP: (.-) %(for Auth%.: (.-)%)") do
	if ike1t ~= nill then
    	ike1=ike1t; ike2=ike2t; ike3=ike3t
    	esp1=esp1t; esp2=esp2t
    end
end
if ike1 ~= nil then print("IKE = " .. ike1 .. "/" .. ike2 .. "/" .. ike3 ); print("ESP = " .. esp1 .. "/" .. esp2 )
else print("No [IKEex] log data!") end

 -- Local ID(Responder)/Remote ID(Initiator)
local idl, idr
for idlt,idrt in string.gmatch(logData, "%[IKEex%] Local ID: ([%d%.]-)%s.-%[IKEex%] Remote ID: ([%d%.]-)%s") do
	if idlt ~= nill then
    	idl = idlt; idr = idrt
    end
end
if debugf then print("Local ID(responder) = " .. idl ); print("Remote ID(initiator) = " .. idr ) end

-- IKE CKY-I / Skeyid_e
local tcky, eky1, eky2
for tcky,eky1,eky2 in string.gmatch(logData, "%[IKE%] CKY%-I%s.-%[IKE%]   ([%x ]+)%s.-%[IKE%] SKEYID_e%s.-%[IKE%]   ([%x ]+)%s.-%[IKE%]   ([%x ]+)") do
	if tcky ~= nil then
		cky_i = string.gsub(tcky," ","")
		skeyid_e = string.gsub(eky1," ","")..string.gsub(eky2," ","")
	end
end
if debugf then print("isakmp cky_i="..cky_i) end
if debugf then print("isakmp skeyid_e="..skeyid_e) end

-- get Skeyid_d
local skeyid_d
local t1, t2
for t1, t2 in string.gmatch(logData, "%[IKE%] SKEYID_d%s.-%[IKE%]   ([%x ]+)%s.-%[IKE%]   ([%x ]+)%s") do
	if t1 ~= nil then
		skeyid_d = string.gsub(t1,"%s","")..string.gsub(t2,"%s","")
	end
end
if debugf then print("sekyid_d = " .. skeyid_d ) end

-- get g(qm)^xy for PSF
local g_qm =""
for t1 in string.gmatch(logData, "%[IKE%] g%(qm%)%^xy%s.-%[IKE%] (.-%[IKE%]) protocol") do
	if t1 ~= nil then
		local t3 = string.match(t1, "(omitted)")
		if t3 ~= nil then modpf = false else modpf = true end
		t2 = string.gsub(t1,"%d-%/%d-%/%d- %d+%:%d+%:%d+%: %[IKE%]","")
		g_qm = string.gsub(t2,"%s","")
	end
end
if g_qm ~= ""  then if modpf then print("pfs on") else print("pfs on but partialy omitted!") end end
if debugf then if g_qm ~= "" then if modpf then print("g_qm = " .. g_qm ) else print("above modp1024") end end end
if not modpf then g_qm = "" end

-- get protocol
local protocol
for t1 in string.gmatch(logData, "%[IKE%] protocol = (%d-)%s") do
	if t1 ~= nil then
		protocol = string.format("%02d", tonumber(t1, 16))
	end
end
if debugf then print("protocol = " .. protocol ) end

-- get SPI_r and SPI_i
local spi_r, spi_i
for t1, t2 in string.gmatch(logData, "%[IKE%] SPI%s.-%[IKE%]   ([%x ]+)%s.-%[IKE%] SPI%s.-%[IKE%]   ([%x ]+)%s") do
	if t1 ~= nil then
		spi_r = string.gsub(t1, "%s", "")
		spi_i = string.gsub(t2, "%s", "")
	end
end
if debugf then print("SPI_i = " .. spi_i  .. "\nSPI_r = " .. spi_r) end

-- get Ni_b
local ni_b
for t1 in string.gmatch(logData, "%[IKE%] Ni_b%s.-%[IKE%]   (.-%[IKE%]) Nr_b") do
	if t1 ~= nil then
		t2 = string.gsub(t1,"%d-%/%d-%/%d- %d+%:%d+%:%d+%: %[IKE%]","")
		ni_b = string.gsub(t2,"%s","")
	end
end
if debugf then print("ni_b = " .. ni_b ) end

-- get Nr_b
local nr_b
for t1 in string.gmatch(logData, "%[IKE%] Nr_b%s.-%[IKE%]   (.-%[IKE%]) key material") do
	if t1 ~= nil then
		t2 = string.gsub(t1,"%d-%/%d-%/%d- %d+%:%d+%:%d+%: %[IKE%]","")
		nr_b = string.gsub(t2,"%s","")
	end
end
if debugf then print("nr_b = " .. nr_b ) end

-- get the SPI and the encryption key of Responder
local spi,ekey
pb,pe,spi,ekey = string.find(logData,"%[IKE%] SPI%s.-%[IKE%]   ([%w ]+).-%[IKE%] key material %(first 16byte%)%s.-%[IKE%]   ([%w ]+)",pe)
if pb ~= nil then
	rspi = spi
	rekey = ekey
	pos = pe
else
	rt.syslog("info","[LUA] "..arg[0].." No Responder SA...")
end

-- get the SPI and the encryption key of Initiator
pb,pe,spi,ekey = string.find(logData,"%[IKE%] SPI%s.-%[IKE%]   ([%w ]+).-%[IKE%] key material %(first 16byte%)%s.-%[IKE%]   ([%w ]+)",pe)
if pb ~= nil then
	ispi = spi
	iekey = ekey
else
	rt.syslog("info","[LUA] "..arg[0].." No Initiator SA...")
end
if rspi ~= nil then rspi=string.gsub(rspi," ","") end
if ispi ~= nil then ispi=string.gsub(ispi," ","") end
if rekey ~= nil then rekey=string.gsub(rekey," ","") end
if iekey ~= nil then iekey=string.gsub(iekey," ","") end

-- Get the Global IP Address of Responder
rip=string.match(logData,"PP IP Address Local: ([%d%.]+),")

print("")
tt3 = os.time() -- picking up data
---- IKE
local ikecryptkey
if ike1 == "AES-CBC" then
	ikecryptkey = string.sub(skeyid_e, 1, 32)
elseif ike1 == "AES256-CBC" and ike2 == "SHA2-256" then
	ikecryptkey = string.sub(skeyid_e, 1, 64)
elseif ike1 == "AES256-CBC" and ike2 == "SHA-1" then
	local key1 = sha1.hmac( hex2bin( skeyid_e ), hex2bin("00") )
	local key2 = sha1.hmac( hex2bin( skeyid_e ), hex2bin( key1 ) )
	ikecryptkey = string.sub( key1 .. key2, 1, 64 )
else
	print("IKE key is NOT AES")
end
tt4 = os.time() -- sha1.hmac for ike mt2
if ikecryptkey ~= nil then print("IKE crypt key = " .. ikecryptkey) end
if skeyid_e ~= nil then print("loged IKE key = " .. skeyid_e ) end

---- ESP
local espcryptkey_i, espcryptkey_r, km1_i, km1_r, km2_i, km2_r
tt5 = os.time() -- sha1.hmac for esp mt1
if ike2 == "SHA-1" then
	km1_i = sha1.hmac( hex2bin(skeyid_d), hex2bin(g_qm .. protocol .. spi_i .. ni_b .. nr_b) )
	km1_r = sha1.hmac( hex2bin(skeyid_d), hex2bin(g_qm .. protocol .. spi_r .. ni_b .. nr_b) )	
	if esp1 == "AES-CBC" then
		espcryptkey_i = string.sub( km1_i, 1,32 )
		espcryptkey_r = string.sub( km1_r, 1,32 )
	elseif esp1 == "AES256-CBC" then
		km2_i = sha1.hmac( hex2bin(skeyid_d), hex2bin(km1_i .. g_qm .. protocol .. spi_i .. ni_b .. nr_b) )
		km2_r = sha1.hmac( hex2bin(skeyid_d), hex2bin(km1_r .. g_qm .. protocol .. spi_r .. ni_b .. nr_b) )
		espcryptkey_i = string.sub( km1_i .. km2_i, 1,64 )
		espcryptkey_r = string.sub( km1_r .. km2_r, 1,64 )
	else
		print("ESP key is NOT AES")
	end		
elseif ike2 == "SHA2-256" then
	km1_i = sha2.hmac_sha256( hex2bin(skeyid_d), hex2bin(g_qm .. protocol .. spi_i .. ni_b .. nr_b) )
	km1_r = sha2.hmac_sha256( hex2bin(skeyid_d), hex2bin(g_qm .. protocol .. spi_r .. ni_b .. nr_b) )
	if esp1 == "AES-CBC" then
		espcryptkey_i = string.sub( km1_i, 1,32 )
		espcryptkey_r = string.sub( km1_r, 1,32 )
	elseif esp1 == "AES256-CBC" then
		espcryptkey_i = string.sub( km1_i, 1,64 )
		espcryptkey_r = string.sub( km1_r, 1,64 )
	else
		print("ESP key is NOT AES")
	end		
else
	print("ESP key is NOT SHA-1 or SHA2-256")
end	
tt6 = os.time() -- for esp mt2
print("")
if espcryptkey_i ~= nil then print("ESP crypt key(Initiator) = " .. espcryptkey_i ) end
if iekey ~= nil then print("loged ESP key(initiator) = " .. iekey ) end
print("")
if espcryptkey_r ~= nil then print("ESP crypt key(Responder) = " .. espcryptkey_r ) end
if rekey ~= nil then print("loged ESP key(responder) = " .. rekey ) end

-- ikev1_decryption_table file for Wire Shark
if not ( cky_i == nil or ikecryptkey == nil ) then
    sendconf=string.format("%s,%s\n",cky_i, ikecryptkey)
    local fh,estr,ecode = io.open(filepath..dt.."ikev1_decryption_table","w")
    if fh == nil then
	    -- fh:close()
	    return nil,estr,ecode
    else
	    fh:write(sendconf)
	    fh:close()
    end
end

--- esp_sa file for Wire Shark
--- "AES-CBC [RFC3602]" for aes128, aes256
--- "HMAC-SHA-1-96 [RFC2404]"/"HMAC-SHA-256-128 [RFC4868]"
if not ( idl == nil or idr == nil or spi_i == nil or spi_r == nil ) then

    if esp2 == "HMAC-SHA" then
	    sendconf=string.format("%q,%q,%q,%q,%q,%q,%q,%q\n","IPv4",idl,idr,"0x"..spi_r,"AES-CBC [RFC3602]","0x"..espcryptkey_r,"HMAC-SHA-1-96 [RFC2404]","")
	    receiveconf=string.format("%q,%q,%q,%q,%q,%q,%q,%q\n","IPv4",idr,idl,"0x"..spi_i,"AES-CBC [RFC3602]","0x"..espcryptkey_i,"HMAC-SHA-1-96 [RFC2404]","")
    elseif esp2 == "HMAC-SHA256" then
	    sendconf=string.format("%q,%q,%q,%q,%q,%q,%q,%q\n","IPv4",idl,idr,"0x"..spi_r,"AES-CBC [RFC3602]","0x"..espcryptkey_r,"HMAC-SHA-256-128 [RFC4868]","")
	    receiveconf=string.format("%q,%q,%q,%q,%q,%q,%q,%q\n","IPv4",idr,idl,"0x"..spi_i,"AES-CBC [RFC3602]","0x"..espcryptkey_i,"HMAC-SHA-256-128 [RFC4868]","")
    else
	    sendconf=string.format("%q,%q,%q,%q,%q,%q,%q,%q\n","IPv4",idl,idr,"0x"..spi_r,"AES-CBC [RFC3602]","0x"..espcryptkey_r,"","")
	    receiveconf=string.format("%q,%q,%q,%q,%q,%q,%q,%q\n","IPv4",idr,idl,"0x"..spi_i,"AES-CBC [RFC3602]","0x"..espcryptkey_i,"","")
    end

    fh,estr,ecode = io.open(filepath..dt.."esp_sa","w")
    if fh == nil then
	    -- fh:close()
	    return nil,estr,ecode
    else
	    fh:write(sendconf)
	    fh:write(receiveconf)
	    fh:close()
    end
end

--- rename log file
fh,estr,ecode=io.open(filepath..logTmp,"r")
if fh == nil then
	-- fh:close()
	print("\nNO "..filepath..logTmp)
else
	fh:close()
	rslt,txt=os.rename(filepath..logTmp,filepath..dt..logTmp)
	if rslt == false then print(txt) end
end
---  overwrite log file with last log data
fh,estr,ecode = io.open(filepath .. dt .. logTmp,"w")
if fh == nil then
	-- fh:close()
	return nil,estr,ecode
else
	fh:write(logPPData .. logData)
	fh:close()
end

tt7 = os.time()
---
print("")
print("log file = " .. os.difftime(tt2, tt1) .. " sec" )
print("picking up data = " .. os.difftime(tt3, tt2) .. " sec" )
print("Calculation key (IKE)  = " .. os.difftime(tt4, tt3) .. " sec" )
print("Calculation key (ESP)  = " .. os.difftime(tt6, tt5) .. " sec" )
print("Total time = " .. os.difftime(tt7, tt1) .. " sec")


(4)実行結果
NVR500で実行


NVR510で実行


 

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

Macbook proのトラックパッド反応が悪化

2020-07-04 10:00:00 | 
Macbook pro retina 15" (Late 2013)のトラックパッド反応が悪化してきた

2020年に入りトラックパッドでドラッグ&ドロップを行うと移動途中でドロップしてしまう。クリックとドラッグを両手で行いカバーしてきたが、これも調子が悪く、Elecomのトラックボール(M-DPT1MR BK)をbluetooth接続した。
しかし、何かおかしい。Macbookの座りが悪くなってきた。
心なしか背面が膨らんでいる。
トラックパッド周りも膨らんできた。

リチウムバッテリーが膨らんできた!

Macbook pro 15" retina ( late 2013 )は、ビンテージ(Vintage)品 オブソリート(obsolete)品になると修理不能となるようだ。。。
バッテリー交換費用は、¥19,800-と。。。
Appleサポートに電話してみたが、Vintage製品は、直営店でないと部品が無いようだ。
また、直営店のサポート予約は、一週間先まで満杯。コロナウィルスの影響で予約枠が少ないようだ。午前0時にアクセスすれば、一週間先の予約枠が取れるかもと言われる。頑張るしか無いようだ。。。
何回か予約サイトをアクセスしているうちに一週間先の日曜日に予約枠が現れる。予約枠のキャンセルが発生したのかも。確保した。

この機種は、本体部分にバッテリーが接着されていて、バッテリー交換と同時に本体上面部分(キーボードとトラックパッドがある部分)の交換も行われる(この部分の価格は、無料)。バッテリー交換価格に含まれているようだ。
修理完了。
消費税込み¥21,780-
コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする