So today I was meant to be helping re-build a deck, but that got postponed to next weekend. Thus, I had an extra free day I wasn’t counting on.
I wound up looking at LinBPQ in detail, to see if I can get it to run. I downloaded the sources, and sure enough, they do compile on my x86-64 laptop, but does it work? Not a chance. Starts parsing the configuration file, then boompa, SEGFAULT
.
I run the binary through gdb, and see this:
GNU gdb (Gentoo 8.1 p1) 8.1 Copyright (C) 2018 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-pc-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: <https://bugs.gentoo.org/>. Find the GDB manual and other documentation resources online at: <http://www.gnu.org/software/gdb/documentation/>. For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from /home/stuartl/projects/6lowham/linbpq/linbpq...done. (gdb) r Starting program: /home/stuartl/projects/6lowham/linbpq/linbpq [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib64/libthread_db.so.1". G8BPQ AX25 Packet Switch System Version 6.0.17.1 November 2018 Copyright � 2001-2018 John Wiseman G8BPQ Current Directory is /var/lib/linbpq Configuration file Preprocessor. Using Configuration file /var/lib/linbpq/bpq32.cfg Conversion (probably) successful Program received signal SIGSEGV, Segmentation fault. 0x00005555555f8a7b in Start () at cMain.c:1190 1190 *(ptr3++) = *(ptr2++); (gdb) bt full #0 0x00005555555f8a7b in Start () at cMain.c:1190 cfg = 0x555555b91c40 ptr1 = 0x555555ba60c0 PORT = 0x5555558f6aa0 FULLPORT = 0x558f7928 NEXTPORT = 0x5555558f6de0 <DATAAREA+832> EXTPORT = 0x7ffff6eb7953 <_IO_file_overflow+291> APPL = 0x5555558f49e0 ROUTE = 0x559085e8 DEST = 0x870b07e2ddd5f300 CMD = 0x5555558d79e0 PortSlot = 2 ptr2 = 0x555555ba6849 "K4MSL Test station \r" ptr3 = 0x55912549 ptr4 = 0x5555558d7183 <COMMANDS+1667> " \003" CWPTR = 0x5555558f6b18 <DATAAREA+120> i = 0 n = 119 int3 = 1435466024 #1 0x000055555563e35c in main (argc=1, argv=0x7fffffffe518) at LinBPQ.c:598 i = 1 user = 0x0 conn = 0x7ffff7ffa298 STAT = {st_dev = 140737354131120, st_ino = 140737488347784, st_nlink = 140737488347780, st_mode = 4160741648, st_uid = 32767, st_gid = 4143745959, __pad0 = 32767, st_rdev = 140737488348192, st_size = 140737488347784, st_blksize = 1700966438, st_blocks = 26577600, st_atim = {tv_sec = 140737354113688, tv_nsec = 140737488348000}, st_mtim = {tv_sec = 140737354113448, tv_nsec = 140737488347780}, st_ctim = {tv_sec = 140737488347984, tv_nsec = 140737354131160}, __glibc_reserved = {1, 4150715120, 0}} PORTVEC = 0x7ffff7ffe6b0
Ookay then… so invalid pointers, what fun! More to the point, have a close look at the underlined addresses… I’m beginning to understand why it was called BPQ32.
The culprit for this wound up being little gems like this:
// Round to word boundary (for ARM5 etc) int3 = (int)ptr3; int3 += 3; int3 &= 0xfffffffc; ptr3 = (UCHAR *)int3;
There were a few other instances of this, and variations on the theme too, but one way or the other, linbpq
basically assumes that all pointers are 32-bits, and so are int
s.
Four hours later, I finally had something that started, but there are probably lots of landmines for anyone running the binary to inadvertently stomp on. The code is pointer-arithmetic city! Much of the time, code is casting pointers to unsigned int
, or back again. If I submitted code like that at work, they’d have me hauled ’round the back of the building and shot!
I’m left wondering if it’s worth getting to understand, or should I shove it in a VM, write some code based on my understanding of the protocols, do some integration testing with it, then abandon LinBPQ for something I can have confidence in.
The use and re-use of certain variables makes me wonder if the code is actually a port from the DOS-based BPQCode which was likely written in 8086 assembler. This would make a lot of sense as to why I’m seeing the sorts of software coding patterns I’m seeing in that code. The logic seems to have been ported to C just enough to get it to compile and work like the assembly version.
Reasonable enough… but there’s a lot of technical debt there still waiting to be paid back. On paper, there’s a lot of benefit in using LinBPQ as the back-end, and I am thankful that John Wiseman made the decision to release the code under the GPLv3 so that I can at least investigate the possibility of using that code here.
I’ve thrown what I’ve got up on Github for now, and there’s a Gentoo overlay for installing it. Add the overlay and run emerge linbpq
, and you should find yourself with an installation of LinBPQ that just needs some OpenRC scripts and some work with an editor on /var/lib/linbpq/bpq32.cfg
to get going.
If I get further on the code front, I might look at some init scripts, both OpenRC and systemd
ones, then I can produce a few Debian binaries so you can run apt-get install linbpq
on your Raspberry Pi and have a packet station going quickly.
Recent Comments