CRC-8 and Base32 in Powershell

Recently I was looking for functions that could be used in Powershell to calculate CRC-8 checksums and encoding to Base32. Finally I havent found any code that I could use, even trying to import system DLL functions from standard Windows libraries.

My code is published on github here: https://github.com/defragmentator/PowershellTools

  • CRC-8
    1. This implementation is exactly as CRC8-maxim/dallas
    2. Other types of CRC-8: probably it would be easy to implement other types of CRC8 by changing 0X8C in code
$c = (0x8C -bxor ($c -shr 1))

to some other values from Wiki with value of Polynomial representations named there in chart as “Reversed”. It was not testet yet!

  • Base32 is based on regexp so it is very unoptimal, but it works.

Example usage:

$b= [System.Text.Encoding]::ASCII.GetBytes("Power") | Get-Base32

"base32: $b"

$a= [System.Text.Encoding]::ASCII.GetBytes("Power") | Get-CRC8

[String]::Format("{0:x2}", $a)
$a.ToString("X2")

QNAP custom dhcpd config file

In some network I wanted to use QNAP nas (QTS 4.3.4 x64) also as DHCP server, but with my own config file. I needed static bindings and special config with cookie for Smart-UPS RT 10000 XL (which I already mentioned here).
First option was to use some App from AppCenter like DNSMasq (not seen that app? 🙂 You can use alternative repo like https://www.qnapclub.eu/pl/repo/xml – maybe I’ll write something more about that some day), but in my case the default volume is encrypted. As long as I don’t enter password manually after restart or a power failure apps won’t get loaded, so network is dead without DHCP server.
Some solution is to make special not encrypted volume only with that app – but unfortunately most apps does not support volume migration (some other time I will write something more about how to enable this option).
The third solution is to use system dhcp server which is ISC DHCP. It is loaded even when main volume is not mounted. But how to provide custom config premanently?

First of all we need to enable dhcp server in Network & Virtual switch app. In my case br0 interface was used. I propose to configure as small IP range as possible in case if some client succeed to connect before we replace config (just one IP would be fine). Then we put our config file in

/etc/config/dhcpd_br0.conf

For my UPS it was something like:

#custom_config
ddns-update-style none;
get-lease-hostnames true;
default-lease-time 7200;                                                                                                                                                     
max-lease-time 7200;
log-facility local7;
ping-check false;
option apc-token code 43 = string;
authoritative;

subnet 192.168.1.0 netmask 255.255.255.0 {
    option domain-name "domain.org";
    option domain-name-servers 8.8.8.8, 8.8.4.4;
    option routers 192.168.1.1;
    option subnet-mask 255.255.255.0;
    option broadcast-address 192.168.1.255;
    range 192.168.1.71 192.168.1.90;
}

#some static host
host hsot1 {
   fixed-address 192.168.1.2;
   hardware ethernet 04:14:a6:c9:66:78;
}

#Smart-UPS RT 10000 XL  with AP9619 card 
host ups {
   fixed-address 192.168.1.13;
   hardware ethernet 00:ca:a7:62:37:64;
   #cookie needed to get things work
   option apc-token 01:04:31:41:50:43;
}

Then we create

/etc/config/dhcpd_check

file:

#!/bin/sh

/bin/grep -q custom_config /etc/dhcpd_br0.conf || \
    ( cp -f /etc/config/dhcpd_br0.conf /etc/dhcpd_br0.conf && \
    kill `cat /mnt/ext/opt/netmgr/api/core/dhcpdLink/br0.pid` )

That script checks if the current config file is ours. If not it replaces the file and kills dhcpd server. QTS has some kind of watchdog mechanism so we don’t need to bother to start it again (ISC DHCP does not support config reload with signals so more elegant way is not possible 🙁 ). Please remember to set correct permissions by

chmod 700 /etc/config/dhcpd_check

Last thing to do is to add our script to cron by editing

/etc/config/crontab

and adding

* * * * * /etc/config/./dhcpd_check

Not very elegant solution, but works 🙂

UPS on macOS Sierra 10.12 with snmp problem

I’m using Smart-UPS RT 10000 XL on my network and wanted to use it also with my iMac runing macOS Sierra 10.12. An AP9619 card enables user to monitor UPS status with SNMP. For that purpose I installed apcupsd package using Homebrew:

brew install apcupsd

Configuration file is located at:

/usr/local/etc/apcupsd/apcupsd.conf

and there was a need to change some things:

UPSCABLE smart
UPSTYPE snmp
DEVICE 192.168.1.13:161:APC:public

Everything seemed to work, but after some time I noticed that power failure didn’t shut down my iMac.
I noticed that after reboot status check

/usr/local/Cellar/apcupsd/3.14.14/sbin/apcaccess status

resulted in something like that:

APC      : 001,018,0459
DATE     : 2018-02-03 13:27:16 +0100  
HOSTNAME : My-iMac.local
VERSION  : 3.14.14 (31 May 2016) darwin
UPSNAME  : My-iMac.local
CABLE    : Ethernet Link
DRIVER   : SNMP UPS Driver
UPSMODE  : Stand Alone
STARTTIME: 2018-02-03 13:08:14 +0100  
STATUS   : 
MBATTCHG : 5 Percent
MINTIMEL : 3 Minutes
MAXTIME  : 0 Seconds
NUMXFERS : 0
TONBATT  : 0 Seconds
CUMONBATT: 0 Seconds
XOFFBATT : N/A
STATFLAG : 0x05000000
END APC  : 2018-02-03 13:27:44 +0100

I seemed that UPS was not visible. After restarting service

sudo sudo launchctl stop org.apcupsd.apcupsd
sudo sudo launchctl start org.apcupsd.apcupsd

everything was going back to normal:

APC      : 001,046,1075
DATE     : 2018-02-03 13:45:42 +0100  
HOSTNAME : My-iMac.local
VERSION  : 3.14.14 (31 May 2016) darwin
UPSNAME  : UPS
CABLE    : Ethernet Link
DRIVER   : SNMP UPS Driver
UPSMODE  : Stand Alone
STARTTIME: 2018-02-03 13:45:39 +0100  
MODEL    : Smart-UPS RT 10000 XL
STATUS   : ONLINE 
LINEV    : 243.0 Volts
LOADPCT  : 15.0 Percent
BCHARGE  : 100.0 Percent
TIMELEFT : 114.0 Minutes
MBATTCHG : 5 Percent
MINTIMEL : 3 Minutes
MAXTIME  : 0 Seconds
MAXLINEV : 243.0 Volts
MINLINEV : 236.0 Volts
OUTPUTV  : 229.0 Volts
SENSE    : Unknown
DWAKE    : 0 Seconds
DSHUTD   : 20 Seconds
DLOWBATT : 2 Minutes
LOTRANS  : 196.0 Volts
HITRANS  : 253.0 Volts
RETPCT   : 0.0 Percent
ITEMP    : 25.0 C
ALARMDEL : 5 Seconds
BATTV    : 218.0 Volts
LINEFREQ : 49.0 Hz
LASTXFER : Unacceptable line voltage changes
NUMXFERS : 0
TONBATT  : 0 Seconds
CUMONBATT: 0 Seconds
XOFFBATT : N/A
SELFTEST : OK
STESTI   : 336
STATFLAG : 0x05000008
MANDATE  : 07/11/07
SERIALNO : IS000000000
BATTDATE : 07/11/07
NOMOUTV  : 230 Volts
EXTBATTS : 2
FIRMWARE : 476.17.W
END APC  : 2018-02-03 13:45:45 +0100 

After some debugging I realized that daemon is started before network was ready (don’t know if it is a brew package problem or my configuration is specific).
Turned out that apcupsd wasn’t able to use network connection initialized after it’s start. My solution is not very elegant, but fully satisfying – addition of some delay

/bin/sleep  180

in the second line of

/usr/local/Cellar/apcupsd/3.14.14/sbin/apcupsd-start

was sufficient.

Too many pipes open in php-fpm

Configuring php-fpm I had a problem – even when configured in php-fpm.conf

<value name="max_children">150</value>

I got only about 120 childrens.  I found that the problem was krenel maximum open files limit. You can check it with

ulimit -a
core file size (blocks)     unlimited
data seg size (kbytes)      unlimited
file size (blocks)          unlimited
open files                  256
pipe size (512 bytes)       10
stack size (kbytes)         8192
cpu time (seconds)          unlimited
max user processes          29995
virtual memory (kbytes)     unlimited

These values can be globally changed in

/etc/system

. In this case reboot is needed, but for me it was easier  to add

ulimit -n 1024 

at the top

sbin/php-fpm

startup script.

Dynamic library functions’ listing

Sometimes it would be useful to see what functions does export dynamic library.

There is very useful solaris tool which may help

/usr/ccs/bin/nm

example usage:

/usr/ccs/bin/./nm /lib/libmd5.so
/lib/libmd5.so:

[Index]   Value      Size    Type  Bind  Other Shndx   Name

[27]    |         0|       0|SECT |LOCL |0    |1      |
[2]     |       148|       0|SECT |LOCL |0    |1      |
[3]     |       308|       0|SECT |LOCL |0    |2      |
[4]     |       612|       0|SECT |LOCL |0    |3      |
[5]     |       972|       0|SECT |LOCL |0    |4      |
[6]     |      1004|       0|SECT |LOCL |0    |5      |
[7]     |      1060|       0|SECT |LOCL |0    |6      |
[8]     |      1100|       0|SECT |LOCL |0    |7      |
[9]     |      1208|       0|SECT |LOCL |0    |8      |
[10]    |      1268|       0|SECT |LOCL |0    |9      |
[11]    |      5392|       0|SECT |LOCL |0    |10     |
[12]    |      5472|       0|SECT |LOCL |0    |11     |
[13]    |      5600|       0|SECT |LOCL |0    |12     |
[14]    |      5604|       0|SECT |LOCL |0    |13     |
[15]    |     73728|       0|SECT |LOCL |0    |14     |
[16]    |     73740|       0|SECT |LOCL |0    |15     |
[17]    |     73852|       0|SECT |LOCL |0    |16     |
[18]    |     74068|       0|SECT |LOCL |0    |17     |
[19]    |     74108|       0|SECT |LOCL |0    |18     |
[20]    |     74120|       0|SECT |LOCL |0    |19     |
[21]    |     74184|       0|SECT |LOCL |0    |20     |
[22]    |         0|       0|SECT |LOCL |0    |21     |
[23]    |         0|       0|SECT |LOCL |0    |22     |
[24]    |         0|       0|SECT |LOCL |0    |1      |
[25]    |         0|       0|SECT |LOCL |0    |23     |
[26]    |         0|       0|SECT |LOCL |0    |24     |
[43]    |      5304|      88|FUNC |LOCL |0    |9      |Encode
[48]    |      1588|     136|FUNC |GLOB |0    |9      |MD5Final
[52]    |      1268|      60|FUNC |GLOB |0    |9      |MD5Init
[42]    |      1772|    3532|FUNC |LOCL |0    |9      |MD5Transform
[65]    |      1328|     260|FUNC |GLOB |0    |9      |MD5Update
[40]    |     74120|      64|OBJT |LOCL |0    |19     |PADDING
[63]    |         0|       0|OBJT |GLOB |0    |ABS    |SUNW_1.1
[59]    |     73852|       0|OBJT |GLOB |0    |16     |_DYNAMIC
[30]    |     74184|       0|OBJT |LOCL |0    |20     |_END_
[57]    |     73728|       0|OBJT |GLOB |0    |14     |_GLOBAL_OFFSET_TABLE_
[50]    |     73740|       0|OBJT |GLOB |0    |15     |_PROCEDURE_LINKAGE_TABLE_
[28]    |         0|       0|OBJT |LOCL |0    |1      |_START_
[56]    |         0|       0|NOTY |WEAK |0    |UNDEF  |__1cG__CrunVdo_exit_code_in_range6Fpv1_v_
[54]    |         0|       0|NOTY |WEAK |0    |UNDEF  |__1cH__CimplKcplus_fini6F_v_
[58]    |         0|       0|NOTY |WEAK |0    |UNDEF  |__1cH__CimplKcplus_init6F_v_
[35]    |     74112|       0|NOTY |LOCL |0    |18     |_cpp_finidata0
[51]    |     74184|       0|OBJT |GLOB |0    |19     |_edata
[62]    |     74184|       0|OBJT |GLOB |0    |20     |_end
[61]    |      5864|       0|OBJT |GLOB |0    |13     |_etext
[60]    |         0|       0|NOTY |WEAK |0    |UNDEF  |_ex_deregister
[36]    |      5600|       0|NOTY |LOCL |0    |12     |_ex_range0
[46]    |      5600|       0|NOTY |LOCL |0    |12     |_ex_range1
[53]    |         0|       0|NOTY |WEAK |0    |UNDEF  |_ex_register
[34]    |     74084|       0|NOTY |LOCL |0    |17     |_ex_shared0
[45]    |     74100|       0|NOTY |LOCL |0    |17     |_ex_shared1
[37]    |      1268|       0|NOTY |LOCL |0    |9      |_ex_text0
[47]    |      5392|       0|NOTY |LOCL |0    |9      |_ex_text1
[32]    |      5472|     128|FUNC |LOCL |0    |11     |_fini
[29]    |      5392|      80|FUNC |LOCL |0    |10     |_init
[31]    |      5604|       4|OBJT |LOCL |0    |13     |_lib_version
[55]    |         0|       0|FUNC |GLOB |0    |UNDEF  |bcopy
[49]    |         0|       0|FUNC |GLOB |0    |UNDEF  |bzero
[33]    |         0|       0|FILE |LOCL |0    |ABS    |crti.s
[44]    |         0|       0|FILE |LOCL |0    |ABS    |crtn.s
[1]     |         0|       0|FILE |LOCL |0    |ABS    |libmd5.so.1
[39]    |         0|       0|FILE |LOCL |0    |ABS    |md5.c
[64]    |      1724|      48|FUNC |GLOB |0    |9      |md5_calc
[41]    |      5608|     256|OBJT |LOCL |0    |13     |md5_consts
[38]    |         0|       0|FILE |LOCL |0    |ABS    |values-Xa.c</em></blockquote>

Shared libraries conversion

I was wondering if it’s possible to convert binary dynamic library to a shared static library and vice versa.  I’ve done some research and I found a solution to do it but only in one direction.

ar -x libtermcap.a

extracts static library to .o object, then you can compile it to dynamic library

gcc -shared *.o -o libtermcap.so.2

Unfortunately it looks like that conversion in opposite direction is impossible.

php-fpm on Solaris 9 Sparc

If  any one was trying to use php-fpm knows that on Sparc platform have seen: “unsupported processor. please write a patch and send it to me”.

Php-fpm is a great project, so I decided to write my own patch for php 5.2.10 – you can download it here.

Mainly I’ve added necessary assembler code in /sapi/cgi/fpm/fpm_atomic.h for Sparc platform.  Patch also solves issues which I found on my Solaris 9 :

-broken switching between systems with inttypes.h or  stdint.h – I added #if HAVE_INTTYPES_H directives in few places

-if system doesn’t have unsetenv() function it won’t compile – I added #ifndef HAVE_UNSETENV and my implementation of this function in /sapi/cgi/fpm/fpm_env.c if wasn’t in system

-in /sapi/cgi/fpm/fpm_env.c setenv() function wasn’t working properly – on my solaris 9 was adding some stupid data do ENV, I don’t know if it was ok or not on other systems. I’ve rewritten it in other way.

– when /libevent/libevent.a was compiling no proper /libevent/event-config.h was generated. It was a problem when for example system doesn’t have stdint.h – I  added this file in
/libevent/Makefile.in like this “libevent.a: event-config.h $(libevent_a_OBJECTS) $(libevent_a_DEPENDENCIES)”  and changed order in /sapi/cgi/Makefile.frag to: “$(SAPI_CGI_PATH): $(PHP_GLOBAL_OBJS) $(SAPI_EXTRA_DEPS) $(PHP_SAPI_OBJS)

Now as I tested everything compiles and work on Solaris 9 Sparc even in 64bit mode. I’m using it on site with about 250 000 shows per day and for now have no problems. It should be universal for all platforms now! 🙂