The interactive version of this site requires JavaScript; a text version follows.
F

fenyo.net

Alexandre Fenyo — Network & security engineer. Compulsive builder of everything else.

This is not a blog. It is the workshop notebook of someone who has been wiring computers to the world since a Commodore PET in 1979 — software, electronics, drones, home automation, a little radio, and a household of animals that refuse to learn human languages.

Software

Apps, open-source tools, and a few honest patches, written by A. Fenyo.

From the App Store to npm to a couple of binaries that probably should not exist. Most of it solves a problem no web service ever bothered to.

Captured!

Your universal share box — capture, organize and AI-enrich anything you share, all on-device.

  • Platform: iOS · iPadOS · macOS · visionOS
  • Price: Free
  • Privacy: No account · no server · no ads
  • Languages: 44

Tired of losing the links people send you, the photos you want to find again, the articles to read later, the documents shared in Files or Messages? Captured! is your universal clipboard. From any app, tap Share and choose Captured: URLs, text, images, videos, PDFs, spreadsheets, contacts — all captured, organized and enriched in an interface designed for iPhone and iPad.

It began as a tool I built for myself, to watch YouTube videos without any ads. Then I added the ability to view almost anything — photos, videos, office documents — and integrated Apple Intelligence, OpenAI GPT-4 Vision and Anthropic Claude to run OCR and automatically describe the thumbnails of documents, photos, videos and URLs.

Those AI-generated descriptions are indexed with Spotlight, so the system search on your iPad or iPhone can find items stored inside the app among everything else on the device. Your data stays on the device, with optional, folder-by-folder iCloud sync — no account, no server, no ads.

A small confession: this one went from personal tool to App-Store quality in three evenings, with the help of Claude Code — logo, 44 translations, store metadata and all.

Network 3D WiFi Tools

Network tools no web server can give you — latency, throughput, device discovery, and Wi-Fi heat maps.

  • Platform: iOS · iPadOS · macOS
  • Language: Swift

Full disclosure on why this page exists at all: the revenue this little app earns on the App Store helped me — notably — buy the convertible of my dreams, a Mazda MX-5 ND with Brembo brakes. So yes, network tools can pay for a drop-top.

My first iOS app: a toolbox of network tools that simply are not available from web servers. You do not need an app to resolve a DNS name, run a Whois query or geolocate an IP — but you absolutely need one to estimate local latency or throughput, or to discover the devices connected to your local network. This is the Swiss-army knife for network exploration and troubleshooting.

It computes Wi-Fi heat maps from a set of measurements using Inverse Distance Weighting (IDW) interpolation — more precisely a variation of Shepard's method with a power setting of 5, bounded by the convex hull of the measurement positions. The convex hull is computed with Graham's scan, whose time complexity is O(n log n).

VPN-over-DNS

Tunnel application data over DNS queries and answers. 50,000+ users.

  • Platform: Android · macOS · Windows
  • Users: 50,000+

My first Android application, shipped with an account to connect to my VPN server farm. In a few words: it lets users tunnel data through a DNS server — data exfiltration for the times when everything else is blocked. DNS tunneling simply encapsulates data over DNS queries and answers so two parties can communicate across a network of DNS resolvers and servers.

But this is not IP-over-DNS: it carries application data (mail content or web pages) directly on top of DNS queries and answers — far fewer layers. Data is GZIP-compressed before it hits the network, then parsed and filtered to remove non-informational content: MIME attachments and HTML parts in mail, and images, JavaScript, CSS and cookies on web pages, are all stripped just before sending. That increases usable bandwidth a lot.

To make this direct encapsulation work, I had to develop and integrate an optimized native browser and a simple Mail User Agent inside the app. That was the hard part — implementing IP-over-DNS would not have needed any user agent. Re-implementing the user agents is what made it fast and usable even if you are not a network engineer. That was the challenge.

On 10 February 2015, VPN-over-DNS reached its 50,000th user.

Netman Reborn — Etherman + Interman

A faithful modern recreation of the Netman suite’s Etherman (L2) and Interman (L3), side by side in the browser from a single live capture.

  • Backend: Rust · Npcap · axum
  • Frontend: sigma.js v3 · graphology
  • Layers: L2 (MAC) + L3 (IPv4/IPv6)
  • Mode: Strictly passive
  • OS: Windows 10/11

A modern recreation of two tools from the Netman suite (Curtin University, 1993): Etherman (layer-2 conversations, MAC addresses) and Interman (layer-3 conversations, IPv4 + IPv6), shown side by side in the browser and fed by a single network capture.

Why this project? I used the original Netman tools — Etherman, Interman and the others — on a Sun SPARCstation under SunOS 4.1.2, in the very early 1990s, at Télécom Paris, my engineering school. This repository is a modern recreation, faithful to their look and spirit.

A Rust backend handles Npcap capture, aggregation and an HTTP/WebSocket server (axum). The sigma.js v3 + graphology frontend lays Etherman’s stations on a single circle (a flat L2 network) while Interman draws one circle per network (classful IPv4, /64 IPv6), the networks spread around a ring. The tool is strictly passive: capture and display only, no injection.

Etherman (left): one node per MAC address (vendor-labelled from the embedded Wireshark OUI database), one edge per L2 conversation, all stations sharing one segment — conversations crossing the circle, just like the 1993 Etherman. Interman (right): one node per IP (v4/v6, remote networks included), auto-renamed as soon as reverse-DNS resolves, one edge per L3 conversation, hosts of the same classful network forming one circle each.

Visual mapping: node size ∝ log(cumulative bytes); edge width ∝ log(observed throughput, smoothed over ~3 s); colour = dominant protocol. Controls include Pause/Resume, Reset, per-link average bidirectional rate display, single-protocol highlight, and a synchronized Fade delay (5 s → 10 min). Hovering a node shows the full MAC or IP, resolved name, and in/out throughput.

GNetWatch — real-time network monitoring & analysis

Real-time, open-source network analyzer driving SNMP and ICMP, with two traffic-generation modules.

  • Platform: Java · Linux · Windows · Docker
  • License: GPL
  • Latest: v4.1 (2016)
  • Protocols: SNMPv1/v2c/v3 · ICMP
  • Networks: IPv4 & IPv6

GNetWatch is a free, open-source Java application offering real-time graphical monitoring and analysis of network performance through SNMP and ICMP. To give an instant view of the network state, data is collected, stored and displayed every few seconds.

Two traffic-generation modules are available. The first can flood UDP packets of any size — jumbo frames, for instance — tagged with any DiffServ/ToS flag, for QoS and class-of-service testing. The second can generate a huge quantity of parallel requests against any HTTP(s) server, for web-application load testing.

To automatically discover new hosts, GNetWatch can make use of Ethereal/Wireshark and then invoke Nmap to gather information about the remote systems. IPv6 and SNMPv3 are fully supported.

Main features — it can flood packets with any DiffServ codepoint, especially those of RFC-2597 (Assured Forwarding) and RFC-2598 (Expedited Forwarding); talk SNMPv1, SNMPv2c and SNMPv3 (MD5 + DES); run on IPv4 and IPv6 networks; and generate Ethernet jumbo frames.

Graphic performance — GNetWatch uses SWT and AWT simultaneously: the main GUI is drawn with SWT for direct access to the underlying windowing system, while the animated graphs are rendered with Java2D over AWT.

The fifth edition of "A Guide to Customer User Support, for Help Desk and Support Specialists" references GNetWatch as an alternative to OpenNMS — thanks to the author of the book!

net-monitor — live networking charts toolkit

A client/server toolkit to embed live, animated networking charts into web pages — with a built-in SNMP v1/v2c/v3 manager, over WebSockets.

  • Registries: npm · DockerHub · GitHub
  • Client: JS + Chart.js
  • Server: servlet (Tomcat)
  • SNMP: v1 · v2c · v3
  • IP: IPv4 & IPv6

net-monitor is a client / server toolkit whose purpose is to let you include HTML animated networking charts into your web applications and single pages. It ships with an SNMP v1/v2c/v3 manager and is fully compliant with IPv4 and IPv6.

It is made of two main parts: a JavaScript client library (net-monitor.bundle.min.js), and a server running in a servlet container that collects data and feeds the client library. The implementation is very efficient — clients do not poll the server; instead they subscribe to their desired topics (data sets) from a message broker, on top of WebSockets. A very large number of clients can therefore connect to the same server without performance issues.

Two live demos display the ingress and egress throughput of my home ADSL box: a blank-background one showing 120 seconds, and a black-background one showing 30 seconds. There is also a JSFiddle running with live data, and a short video of net-monitor on a small Raspberry-Pi display in kiosk mode (links below).

Core concept — data set: a named time series (a set of timestamped values) maintained in the server memory, typically network throughput collected from an SNMP agent, each with a maximum lifetime. The only way to create a data set is to push a value to a name that does not yet exist, and only probes can do that. No value can be timestamped in the past or future; when two values become older than the lifetime the oldest is dropped (one stale value is kept so the left-most chart segment can be drawn).

Core concept — probe: collects real-time data and pushes it to a data set. Internal probes run inside the server (currently SNMP probes collecting interface throughput, with a constant lifetime); external probes run anywhere and call a REST/JSON web service to push data — including your browser itself, via NetMonitor.pushValue(...), with a lifetime that may change over time.

Core concepts — chart, view, manager: a chart is a Chart.js object drawing a series on a canvas; a view binds a chart to the last X seconds of a data set (X is the x-axis time scale); a manager (running in the browser) ties views to data sets — it creates the chart, opens a WebSocket to subscribe to new values, downloads the in-range history (plus one older value), then draws and scrolls the chart as values arrive. Create several managers to show the same data set at several time scales.

Lifetime rules: four lifetimes exist — the server default, the data-set lifetime, the lifetime a probe specifies on push, and the constant lifetime of a view. A data-set lifetime can only ever be increased, never decreased; always push (or configure a probe with) a lifetime greater than the widest view time-scale that will display it.

Server configuration uses two files: log4j.xml (optional logging rules) and the mandatory config.json (RFC-7159) holding default_lifetime and a probes array. Every SNMP probe needs: dataset, lifetime, type ("snmp"), version (v1/v2c/v3), agent (DNS/IPv4/IPv6), oid (a Counter OID such as IF-MIB::ifInOctets.[index]) and rate (≈ ten times the OID update rate, so throughput = Δvalue / Δtime stays accurate). v1/v2c also need community; v3 needs username, sec_level (noAuthNoPriv / authNoPriv / authPriv) and the matching auth_algo/priv_algo + secrets.

0x800 — 2048 in hexadecimal

2048, rewritten in hexadecimal. Have fun.

  • Platform: Web
  • Tech: HTML + JavaScript

My own version of the 2048 game: I patched an HTML+JavaScript version originally written by Gabriele Cirulli and changed the tiles to hexadecimal numbers — the first version of 0x800, especially for gamers who understood the advantages of hexadecimal notation. Have fun!

My Android bug report to Google — accepted and patched

I reported a TLS SNI bug on Android ICS; Google confirmed it and the platform was patched.

  • When: Summer 2012
  • Device: Galaxy S2 · ICS
  • Spec: SNI (RFC 3546)

In the summer of 2012 I hit a bug on Android ICS with my Galaxy S2: connecting to a TLS-secured, multi-homed web server using SNI (RFC 3546) was impossible whenever the phone went through a proxy on a Wi-Fi network.

Google confirmed the bug and Android was patched. This matters because SNI is the only secure way to let several secured servers share a single IPv4 address — alternatives such as certificates with multiple subject-alternative names carry security issues, since one certificate is then shared across servers that may not belong to the same company.

KIF — Kit d’Intégration à FranceConnect

A production-grade FranceConnect service-provider POC and a relay IdP that drops FranceConnect login into any existing app.

  • Functions: KIF-SP + KIF-IdP
  • Stack: JEE · Spring Security · MITREid Connect
  • Protocol: OpenID Connect
  • Throughput: 2–6.5 M auth/day, 1 core
  • License: Apache-2.0

KIF (Kit d’Intégration à FranceConnect) has two goals: first, to provide a complete, production-grade and well-documented example of a FranceConnect service provider in a JEE environment, using Spring Security and MITREid Connect (the MIT reference implementation of OpenID Connect), with logout, tracing and authentication-error handling built in; second, to make it easy to add FranceConnect authentication to an existing application in any technology (JEE, Ruby on Rails, Perl/CGI, PHP, Node.js...), by connecting it to the internal IdP that KIF provides.

KIF is therefore both a service-provider POC (KIF-SP) and a relay IdP (KIF-IdP) sitting between a legacy application and the FranceConnect IdP. Both functions are hosted online so you can test them without installing anything, and a single Docker image bundling KIF-SP and KIF-IdP is published on Docker Hub — a working instance in a few minutes, on your own server or a major Docker cloud (AWS, GCP, Azure, OpenShift, OVH...).

A separate FranceConnect stub (« bouchon »), also shipped as a Docker image, lets any FranceConnect service-provider developer work offline, run load tests, or simulate error cases. It is independent of KIF-SP and KIF-IdP, so it works with any service provider built on any library.

Performance allows large-scale deployment: KIF can perform 2 million authentications per day on a single Xeon E5-2666 v3 core, and up to 6.5 million per day on one core when SSL/TLS is offloaded to a hardware accelerator. Deployment was tested successfully on Tomcat, Jetty and WildFly, and on Linux (Ubuntu, SLES, OpenSUSE, Amazon Linux), Docker and FreeBSD.

Configuration uses two files. config.properties (created from config.properties-template in FournisseurDeServices/src/main/webapp/META-INF) holds the parameters — and secrets, so its filesystem permissions must be locked down. log4j.xml (Log4j 1.2 format) drives tracing, with ready-made log4j-devel.xml (verbose) and log4j-prod.xml (production: warn for everything, info for KIF — logging each session create/destroy, authentication, auth error and logout with the JSESSIONID, a request reference, the client IP and TCP port, the error cause, and the live session count for capacity planning).

KIF-SP parameters configure the four OpenID Connect endpoints (FranceConnect authorize / token / userinfo, plus the service-provider redirect URI), the mutual-trust client id, client secret and issuer, the global-logout mechanism, and the service-provider behaviour (session timeout, default 240 minutes — set it below the 30-minute FranceConnect session to get transparent reconnection in some cases). KIF-IdP parameters set the encryption between the integrated application and KIF-IdP: a mode (AES-256-CBC for backward compatibility, the preferred AES-256-GCM), a 256-bit AES key and a 128-bit IV (both generated with openssl rand -hex), and the application callback URI.

Authentication flow (six steps): the Spring MITREid Connect filter detects access to a protected resource and redirects to its callback; finding no id token and no authorization code, it starts the OpenID Connect flow to obtain an authorization code from the authorize endpoint; on the callback it calls the token endpoint (server-to-server REST) to exchange the code for a JWT id token and an access token; it then calls the userinfo endpoint with the access token to fetch the pivot identity (JSON); finally the user is returned to the protected resource. The identity is reconciled by FranceConnect with the RNIPP, so the service provider always receives a civil-status extract from the RNIPP.

Logout flow: it is not specified by OpenID Connect but by FranceConnect, so it was implemented specifically in KIF-SP. On logout, the service provider invalidates the session and redirects to the FranceConnect logout URL, where the user may also disconnect from FranceConnect, then back to the service-provider post-logout URL. As a security best practice, KIF hides the precise cause of an authentication error from the browser: the cause is logged and the user is sent to a generic error page configured by authenticationerroruri.

NDPROXY for FreeBSD

A FreeBSD kernel module for IPv6 Neighbor Discovery proxying — subnet a delegated IPv6 prefix even when your ISP won’t let you.

  • Platform: FreeBSD kernel
  • Protocol: IPv6 ND (RFC-4861)
  • Framework: pfil(9) hook
  • Tested: FreeBSD 10.x – 13
  • Ports: net/ndproxy (since 2017-08)

NDPROXY is a FreeBSD kernel module that implements IPv6 Neighbor Discovery proxying over Ethernet-like access networks, with many options to cover several use-cases. With it, your uplink provider keeps seeing you as a flat network, yet you can subnet your IPv6 prefix and route packets to your preferred gateway — a Cisco router, for instance — that splits your network into several subnets. Your FreeBSD router redirects packets coming from the provider router to that gateway; you just connect one FreeBSD interface to the layer-2 that interconnects your provider and your gateway, and disable MLD snooping on the interconnection switch.

It has been available from the official FreeBSD ports tree since August 2017 (net/ndproxy), so you can get precompiled packages for many targets or build from source with dependency management. Tested successfully on FreeBSD 10.x, 11.x, 12.x and CURRENT (13).

How it works: ndproxy replies to a neighbor solicitation with a specific neighbor advertisement, so the PE uplink router forwards further packets to a CPE downlink router — which may or may not be the node running ndproxy. It hooks the pfil(9) framework to be invoked for every incoming IPv6 packet, filtering neighbor solicitations and answering with the right advertisements. Because ND packets target solicited-node multicast addresses and ndproxy holds no list of hosts to proxy, it cannot join those groups: the listening interface must be put in permanent promiscuous mode, and MLD snooping must be disabled on the VLAN of the PE/CPE interconnect (not on the whole switch). That interface only needs a link-local address — no delegated prefix, no global address.

Difference with ndp(8): the ndp proxy option requires you to list each target address to proxy, and redirects proxied packets to the node running ndp. ndproxy needs no such list, so RFC-4941 temporary addresses — which many operating systems use for outbound connections, for privacy — are proxied too; and it can redirect packets to a separate internal IPv6 router (e.g. one with hardware IPv6 routing) rather than to itself.

Why it exists: connecting a flat IPv6 network to the Internet is trivial with the RFC-4861 ND protocol, but connecting a subnetted prefix depends on ISP support — learning routes over an IGP, a static route to the CPE router, or RFC-3633 DHCPv6 Prefix Delegation. ndproxy is written for subscribers whose ISP supports none of these and therefore cannot natively subnet the delegated prefix. (If the ISP only delegates a /64, subnet an RFC-4193 ULA prefix internally and route the /64 to the single subnet that uses temporary addresses for outbound connections.)

Security hardening: for safety, ndproxy explicitly rejects neighbor solicitations carrying any IPv6 extension header — fragmentation (forbidden in all ND messages by RFC-6980), hop-by-hop, destination/mobility, routing, and AH/ESP. It cannot support SEcure Neighbor Discovery (RFC-3971), since proxying ND packets is itself a form of spoofing.

Two address lists tune the behaviour. Exception addresses (net.inet6.ndproxyconf_exception_ipv6_addresses) are target addresses NOT to proxy — the CPE, the ndproxy host and any other node on the interconnect besides the PE; it can be left empty in a simple design. Uplink addresses (net.inet6.ndproxyconf_uplink_ipv6_addresses) list every source address the PE may use (it should contain at least the PE link-local address): ndproxy only handles packets coming from one of them. A read-only counter, net.inet6.ndproxycount, reports the number of advertisements sent.

ISPEED/OSPEED patch for SOCAT

A patch for SOCAT correcting a bug when changing the default speed of a serial asynchronous line, on systems like FreeBSD.

  • Project: SOCAT
  • Affects: up to 1.7.3.1
  • Platform: FreeBSD
  • Bug: FreeBSD #198441

A patch for SOCAT correcting a bug when changing the default speed of a serial asynchronous line — a bug that occurs on some systems such as FreeBSD.

Synopsis: with SOCAT (at least up to version 1.7.3.1) on systems where the b0 to b4000000 options are not available — like FreeBSD — setting the speed of a TERMIOS terminal is done using the ispeed and ospeed options.

But when ispeed and ospeed are used simultaneously with SOCAT, the speed values are set within two distinct ioctl requests. So changing the speed of terminals or devices that need matching input and output returns an "Invalid argument" error: the TIOCSETA / TIOCSETAW / TIOCSETAF ioctl returns -1 and sets errno to EINVAL.

This is especially the case on FreeBSD, where many tty device drivers need matching input and output speeds: those depending on ucom(4) — uark(4), ubsa(4), ubser(4), uftdi(4), umcs(4), uplcom(4), uslcom(4), uvscom(4) — and some others that do not depend on ucom(4): uart(4), sio(4), digi(4), rp(4). Some, like tty(4), do not.

With those drivers, the input and output speeds must match and be set inside a single ioctl request (TIOCSETA, TIOCSETAW or TIOCSETAF). The only exception is when the input baud rate is zero, because, according to POSIX, the input baud rate is then set equal to the output baud rate.

Eaton Intelligent Power Protector on FreeBSD

How to install Eaton Intelligent Power Protector on FreeBSD, where no native build exists.

  • Platform: FreeBSD 10.1
  • Software: Eaton IPP 1.42.109

Eaton IPP manages UPS units made by Eaton — it launches scripts on events (e.g. power loss) and records logs. But it ships only as a binary distribution, and specifically not for FreeBSD. Here is how to run it on FreeBSD 10.1 using the Linux compatibility layer.

UVSS — Universal Virtual Screening System

Universal Virtual Screening System — pipelines on hundred-processor supercomputers.

  • Platform: Solaris · HP-UX · IRIX · Linux
  • At: Genomining

When I was working at Genomining, I was in charge of designing this software, which manages virtual-screening pipelines on huge supercomputers (hundreds of processors).

Rapid copy of USB key content

Copy, manipulate and erase raw data on a USB flash drive. Real privacy for your files.

  • Platform: Windows
  • License: GPL
  • Year: 2006

This software manages raw data drives. It was designed to handle USB flash keys — copy a key to a file so you can analyze it later, securely wipe it so nobody can recover previously erased files, or simply read its low-level information.

A hidden VNC server — no tray icon

A patch for WinVNC 4 — no more tray icon.

  • Platform: Windows XP
  • Type: Patch
  • Base: RealVNC 4.1.2
  • Author: Alexandre Fenyo

The RealVNC tray icon is designed to tell the user when someone is watching their display: it changes from a white to a black background. This patch for the RealVNC 4 server lets you install a hidden RealVNC server — users will never see the tray icon.

Installation: download the three files below (the VNC self-extracting distribution and the two patched files). First install the VNC server as a service started at boot time, then configure it. Finally, replace winvnc4.exe and wm_hooks.dll with the patched versions in the installation directory, and restart the computer.

Requesting 802.1X authentication to a new host with hostapd

Better 802.1X authentication on wired IEEE 802 media.

  • Platform: Unix / Linux
  • License: GPL
  • Year: 2006

HOSTAPD is an open tool that implements an 802.1X Authenticator PAE (Port Access Entity). Per IEEE Std 802.1X-2004, the authenticator may initiate the conversation — on wired media a switch starts authentication the moment it detects an electrical signal on a port. A supplicant can also start it with an EAPOL-Start frame, but many PC operating systems never send that first frame.

The problem: HOSTAPD is a generic software implementation and cannot detect an electrical signal on a port, so it falls back to spotting new devices via their DHCP broadcasts. This means you cannot use fixed IP addresses with HOSTAPD on wired IEEE 802 media.

This patch implements a workaround: it adds a CLI command that starts the authentication process for a specified MAC address. You can now automate authentication from any source — for instance, by snooping the network for new MAC addresses.

Pairing with Le Cube from Canal+

A 2013 proof-of-concept: brute-forcing the pairing of a Canal+ set-top box that no longer exists.

  • Year: 2013
  • Platform: Unix / Linux / Cygwin
  • Needs: Perl + Zsh
  • Status: Historical — device discontinued

A historical curiosity, kept here to document a security flaw from the past. This package dates back to 2013 and targets the "+Le Cube" / "Le cube Canal+" set-top box — a product that no longer exists. It is published only to illustrate how a weak pairing scheme could be defeated; there is nothing left to attack.

The package contains a set of UPnP scripts that automate the box — changing the volume and selecting channels through its SOAP/UPnP services — plus a brute-force tool that pairs with the box without knowing its 4-digit secret code.

The flaw: to pair, a client sends a UPnP SOAP message with a unique identifier (uuid); the box then picks a number between 0000 and 9999 and waits for a message carrying that number alongside the uuid. The number is shown on the box screen for only 30 seconds, to prove you are physically in front of it. But the box keeps accepting attempts indefinitely, even after the screen is cleared — so the 10,000 possibilities can simply be enumerated. A full brute force takes about 5 to 10 minutes.

Once paired, the scripts read and set the volume, pull the channel list, and switch channels by name (any unique substring of the channel name works).

Maven Wagon with an in-line host key

A patched Apache Maven Wagon that lets you configure the SSH host key inline in settings.xml.

  • Base: Apache Maven Wagon 3.0.1
  • Version: 3.0.1-SINGLE
  • Transport: scp / ssh (Jsch)
  • Language: Java

A patched version of Apache Maven Wagon that supports in-line host-key configuration in settings.xml, through a new hostKey parameter — so a Maven SCP deployment no longer depends on $HOME/.ssh/known_hosts and stays independent from the user context.

The problem: people who want the SingleKnownHostsProvider to supply a host key manually usually try to override the knownHostsProvider with the SingleKnownHostProvider implementation class — but it does not work. When the repository URL starts with scp:, Plexus (Maven’s component manager) looks up the Wagon with hint "scp", whose class (up to 3.0.1) extends AbstractJschWagon. That class statically requests its KnownHostsProvider with role-hint "file", so Plexus always instantiates FileKnownHostsProvider (role-hint "file") and never SingleKnownHostProvider (role-hint "single").

The solution: this package patches AbstractJschWagon to add a hostKey configuration parameter and to skip FileKnownHostProvider whenever that parameter is set. The host name and key given in hostKey are then published as the single known-host entry used when Jsch connects to the remote server. The patched distribution is deliberately renamed 3.0.1-SINGLE, so installing it does not override your existing Wagon.

Usage: clone, build and install it locally (mvn install -DskipTests), declare the 3.0.1-SINGLE wagon-ssh extension in your pom.xml, then add a <hostKey> to the matching server in .m2/settings.xml. Its value is the remote host name (exactly as in the repository url), a space, then the content of the server’s RSA public key — typically /etc/ssh/ssh_host_rsa_key.pub. RSA keys only — do not use DSA or other key types.

JavaShare

A client/server tool for email and file transfer over unreliable, low-bandwidth links — compressed, with resumable transfers.

  • License: GPL
  • Language: Java
  • Runtime: Java 1.1.8 + JFC/Swing 1.1.1
  • Tested: Cassiopeia EM505F · Linux · Solaris 2.7 · Win 98/2000

JavaShare is a client/server application for email and file transfer in unreliable, low-bandwidth environments — for instance a PDA on a PPP link running over an IrDA channel to a mobile GSM phone. Communications are compressed, and an interrupted transfer is restarted from the last position.

It runs in one of two modes. As a server (java ShareFiles server), it serves a Unix-format mailbox file named "mailbox" from its working directory (a symlink works). As a client, you set the remote server host and a local directory, fetch the remote directory listing, then send a selected local file or retrieve a selected remote one. "Check mail" downloads the remote "mailbox" file and JavaShare then acts as a local POP3 server, handing those mails offline to your own Mail User Agent.

On a PocketPC, its main advantage is to bring mail into Pocket Outlook while offline: you create a POP3 loopback connection (mail server 127.0.0.1) so Pocket Outlook reads from JavaShare’s local POP3 server. But Windows CE refuses to retrieve POP3 mail when not connected to a service, so the loopback trick cannot work offline — for that case, MBOX2MAPI extracts a Unix mailbox straight into the Message Store instead.

Built with JDK 1.1.8, it runs on any Java 1.1.8 runtime with JFC/Swing 1.1.1. It has been tested on a Cassiopeia EM505F, Linux, Solaris 2.7 and Windows 98/2000, and should run on WinCE 2.11 / 3.0 (PocketPC), Windows 98/NT/2000 and most Unix systems.

avi2ppm

A Windows transcoder that explodes any AVI into one PPM image per frame.

  • Target OS: Windows 98/NT/2000
  • Language: C++
  • Libraries: Win32 API
  • Tested: Windows 98/2000

I wrote this utility to help process video streams under Unix. avi2ppm is an AVI-to-PPM transcoder running under Windows: it decodes the frames of any AVI file and stores each one as a separate PPM file (Portable PixMap, the standard Unix format). You need the decoding codec matching your AVI file installed on the PC where you run avi2ppm.exe.

Invoked with no argument, avi2ppm displays its help.

mbox2mapi

Advanced control over WindowsCE/PocketPC mail: inject a Unix mailbox into the Message Store, and delete mail offline.

  • License: Freeware
  • Target OS: WindowsCE 3.x / Pocket PC
  • Language: C++
  • Libraries: MFC
  • Tested: Cassiopeia EM505F

MAILBOX2MAPI is a utility that adds advanced control over the mail subsystem of WindowsCE/PocketPC. It offers two functions. First, it extracts a Unix mailbox file into the Message Store, so the user can read those mails directly from Pocket Outlook — especially useful together with JavaShare.

Second, it deletes mails without connecting to the corresponding service. Under WindowsCE/PocketPC you often cannot delete mails while disconnected from the service that added them — meaning you would have to go back online just to delete local mail. With mbox2mapi you can completely erase a folder in a single operation while staying offline.

Used together with JavaShare, mbox2mapi is the best way to retrieve mail in unreliable, low-bandwidth environments — for instance a PDA on a PPP link over an IrDA channel to a mobile GSM phone. Communications are compressed and an interrupted transfer restarts from the last position.

XMLLogs

A framework that automatically builds graphs from web-server logs and publishes them on the web.

  • Target OS: Java VM · Unix · Windows 2000
  • Languages: Java · Perl · Visual Basic

XMLLogs lets you automatically build graphs and publish them on the web. It is a framework assembled from several components.

A Java Application Server (AppServer) — a Windows service for file exchange and remote control of Windows applications; an XML/XSLT application (logs.xsl) that parses and counts web-server logs; an Excel worksheet driven by Visual Basic macros that downloads the XML description of the graph and renders the picture; and some glue software (XML extensions in Java, a DNS caching system in Perl, and so on).

The web graphs are regenerated on a schedule — the published picture is rebuilt automatically every day at midnight. Thanks to Agnès Lefranc for her knowledge of Auto_Open macros in Excel.

Back2Future

A utility that adds extra time to the trial period of WindowsCE/PocketPC sharewares.

  • License: Freeware
  • Target OS: WindowsCE 3.x / Pocket PC
  • Language: C++
  • Libraries: MFC
  • Tested: Cassiopeia EM505F

Back2Future is a utility that adds extra time to the trial period of your WindowsCE/PocketPC sharewares — "the most powerful crack to any PocketPC shareware".

How it works: you launch the command line and click "Past" — the device clock is set to the last time the shareware exited. Click "Launch" to start the shareware. When the shareware exits, Back2Future automatically resets your PDA clock to the correct value and updates the configuration file (soft.crk) with a past date matching the time the shareware exited.

Installation: copy back2future.exe into a program directory (e.g. \My Documents\back2future.exe). To extend \Program Files\share.exe, create a text file (e.g. \My Documents\soft.crk) whose first line is the path to share.exe and whose second line is the date and time of the shareware installation, then run back2future.exe with that file as argument.

Warning: do not use Back2Future while the device is connected to your PC via ActiveSync — ActiveSync regularly resets the PDA clock, which can corrupt the time. Restriction: do not use Back2Future without the authorization of the authors of the sharewares whose trial periods you extend.

MPC-OS

The operating system of the MPC parallel computer — ~40,000 lines of C/C++/perl/X11.

  • Target OS: FreeBSD 3.x
  • Languages: C (kernel & user) · C++ · perl
  • Libraries: STL (C++) · xforms

MPC-OS is the operating system of the MPC parallel computer — about 40,000 lines of mixed C / C++ / perl / shell / XWindow software. Source and binary distributions are available for FreeBSD 3.x, and the package self-configures and compiles via automake/autoconf.

At the kernel level it provides the basic communication layers (hsldriver, PUT, SLR/P, SLR/V), optimized secure layers (DDSCP, RFCP, SFCP, MICP), and an advanced memory-locking system that wires ranges of virtual addresses during inter-node DMA.

On top of that sit a multithreaded Object Request Broker development toolkit and a resource-negotiation manager built on the ORB: a Loader daemon handles task activation, while the manager handles new task activation, application-class creation, channel negotiation between tasks, and allocation/deallocation of kernel data structures for communication end-points. Routing tables are computed automatically from a description of the network topology.

Higher-level facilities include MDCP, a layer over SLR/P offering read/write primitives with no callbacks (zero-copy when write() precedes read()); a SELECT implementation to wait on file descriptors and channels at once; libmpc, a user-level library for issuing manager and MDCP requests; and libsocketwrap, a shared object that wraps the socket API into libmpc calls so any application can be binary-ported to MPC-OS (tested with MPICH on a 2-node MPC computer, distributed computation of PI). The useraccess library exposes the PUT layer at user level.

It also ships many external daemons and tools — monitoring and benchmarking programs (hslclient/hslserver, getevents, vmspace, init_pcibus, readpci/writepci, readphys/writephys, dumpPCIDDC, dumptables, the testput* suite, prot_dump/prot_garbcoll), mpcview (a graphical XWindow interface to manage PCIDDC), a large set of usage examples, and an emulator of the PCIDDC and RCube chips over Ethernet — so you can start developing for MPC without owning any MPC hardware.

EudoPlus

An Eudora add-on that removes the advertisement window from the free full-featured Eudora 5.0.

  • Authors: Alexandre Fenyo & Ag.
  • Target OS: Windows 98/NT/2000
  • Language: C++
  • Libraries: MFC
  • Tested: Windows 98/2000

Ag. and I wrote this add-on to Eudora to get rid of the unpleasant advertisement window in the free, full-featured version of Eudora 5.0.

To install EudoPlus, just copy it into the Eudora installation directory and launch eudoplus.exe instead of eudora.exe: it starts Eudora for you, but without the ads window.

XSU

Graphical tool to start a program under a new user account (root only).

  • Platform: Unix/X11/Xt/OpenLook

A graphical tool to start a program under a new user account (must be root). Provided as-is, with minimal support; sources available on request.

Cecile

A distributed project allocator.

  • Platform: Unix/X11/Xt/Motif

A distributed project allocator. Provided as-is, with minimal support; sources available on request.

nntpgrep

Search NNTP articles by incrementally applying regular expressions.

  • Platform: Perl

Connects to a news server (NNTP) and incrementally applies regular expressions to search for particular articles. Provided as-is; sources available on request.

xloupe

An advanced interactive screen-magnification tool, sold to Aerospatiale.

  • Platform: Unix/XWindow/Xt/Motif

An advanced interactive screen-magnification tool. This program was sold to Aerospatiale — they could perhaps sell it back to you.

AI

Training, fine-tuning and aligning language models — on the hardware I can afford.

Reproducible LLM experiments run on a single H100, an RTX 5090 or rented cloud GPUs — post-training, knowledge injection, retrieval and OCR. Everything is public, with the recipes, the datasets and the pitfalls. Pick a project to read the full write-up.

Qwen2.5-7B base → instruct (SFT → DPO → RLVR)

A full, reproducible pipeline turning a base model into a chat model — and beating the official instruct on instruction-following.

  • Base: Qwen/Qwen2.5-7B
  • Hardware: 1× H100 80 GB
  • Method: SFT → DPO → RLVR
  • Published: hf.co/fenyo/Qwen2.5-7B-base2instruct

A complete and reproducible pipeline that transforms a base model (non-instruct, no chain-of-thought) into a conversational model through SFT → DPO → RLVR, then compares it head-to-head with the official instruct derived from the same base — all on a single H100.

The final model beats the official instruct on IFEval (75.0 vs 71.9) and MMLU (70.2 vs 68.8), trailing only on grade-school math. The progression tells the story: 27 → 51 (SFT) → 69 (targeted DPO, +17.7, the decisive step) → 75 (graduated RLVR). The lesson, verified three times: the training signal must target the exact capability you want.

Documented end to end — the recipe, the pitfalls (DPO NaN in bf16, GRPO binary-reward collapse, an unfair GSM8K eval artifact) and a base→instruct "course" — in RECIPE.md and the Hugging Face model card.

A first iteration (v1) with a generic DPO and a maths RLVR plateaued at 49.5 IFEval; switching to a targeted DPO and a graduated RLVR (v2) made all the difference (+25.5 IFEval). The code is MIT-licensed (the Qwen2.5 base is Apache-2.0).

Mon Espace Santé — knowledge injection (CPT + SFT, H100)

Baking the 88 facts of a public-health FAQ directly into a model’s weights — and outperforming a larger 20B model.

  • Base: Qwen3-14B-Base
  • Hardware: 1× H100 80 GB
  • Method: EntiGraph CPT → SFT
  • Result: Beats gpt-oss-20B

A full reproduction of an experiment: inject the 88 facts of the French public-service "Mon espace santé" FAQ into the weights of Qwen3-14B-Base via massive synthetic generation (EntiGraph + Nemotron-CC FR) → continued pre-training (full fine-tuning) → Q/A-format SFT, then evaluate closed-book.

The resulting 14B model beats gpt-oss-20b-FAQ-MES (a larger 20B model, trained with direct SFT) on a frozen held-out test set: 63.8% strict vs 42.5%, and only 12% hallucination on out-of-domain questions vs 60%. The prior CPT step multiplies precision ×1.7 over SFT alone.

Models, datasets and the frozen evaluation set are published on Hugging Face, alongside the complete pipeline and the major pitfalls solved (DeepSpeed CPU-offload OOM, flash-attn incompatibility, vLLM FP8 DeepGEMM failures).

vec2text for Qwen3-Embedding-0.6B in French — embedding inversion & vector protection for a health RAG

Rebuilding French text from its Qwen3-Embedding vector — then protecting a health RAG’s vectors with de-identification and a secret rotation.

  • Encoder: Qwen3-Embedding-0.6B (1,024 dims)
  • Decoder: Qwen3-0.6B-Base
  • Method: vec2text (Morris et al., 2023)
  • Training: RTX 5090 · ~23 h GPU
  • License: Apache 2.0

RAG systems index documents as embedding vectors, long considered opaque. They are not: a vector holds enough information to rebuild the text — exactly for a short sentence, as a faithful paraphrase for a paragraph. This project builds an inverter for Qwen/Qwen3-Embedding-0.6B in French, following the vec2text method (Morris, Kuleshov, Shmatikov & Rush, EMNLP 2023), then studies how to protect the vectors of a health database.

The inverter is a Qwen3-0.6B-Base decoder, chosen because it shares the encoder’s tokenizer exactly (151,669 identical tokens). The vector is projected into 8 or 16 pseudo-tokens placed at the head of the sequence, and the decoder generates the text. A second model, the iterative corrector, re-encodes each hypothesis and uses the gap between its vector and the target to fix it, step after step, with beam search and cosine re-ranking. Training used ~3 M French passages (Wikipedia, FineWeb-2) plus a health / social-security corpus.

Results on short texts (300 sentences ≤ 32 tokens, 10 steps × beam 8): BLEU 72.4, token F1 90%, 48% of sentences rebuilt exactly; BLEU 78.9 on a health test set. Names, dates, amounts and acronyms are usually recovered. At 128 tokens: BLEU 26, a paraphrase faithful to the subject.

An observation on training the corrector: its training hypotheses must be produced by the inverter on passages it has never seen. Trained on the inverter’s own (memorised) corpus, the corrector learns to barely correct anything (BLEU 48.7 vs 62.8 at 5 steps) — out-of-fold predictions applied to the inverter → corrector chain.

Protection: first de-identify text before encoding — what is not in the text is in no vector. Then rotate the vectors with a secret matrix: a rotation preserves every distance and cosine, so search works identically. The retained construction is a fixed 90° rotation in 512 random planes (K = Q J Qᵀ), so each vector is exactly orthogonal to its image; the key is the choice of planes, derived per user from a master key (HMAC-SHA256) kept in a KMS/HSM. A 30° rotation would leave names and pathologies readable; at 90° the inverter outputs fluent but unrelated text.

This is defence in depth, not encryption: distance-preserving maps fall to known-pair (Procrustes) and known-sample attacks. Measured with these models, an attacker needs ~200 known (text, vector) pairs under one key before anything leaks — hence the sizing rule: at most 100 known pairs and never more than 1,024 vectors per key, one key per user, split by document type and block.

Markdown document search — embeddings + full-text

A benchmark bench comparing semantic and full-text search over Markdown docs, with reranking and HyDE.

  • Vector DB: Qdrant
  • Full-text: OpenSearch
  • UI: Gradio
  • Infra: Docker

A test bench to compare semantic search (embeddings — several models and chunking strategies) against full-text search (OpenSearch), with optional cross-encoder reranking and HyDE (LLM-generated hypothetical documents).

It indexes Markdown files with 4 chunking strategies × 4 multilingual embedding models, runs multi-collection embedding search grouped by model × strategy, reranks with BAAI/bge-reranker-v2-m3, and offers a with/without HyDE comparison powered by Qwen2.5-7B-Instruct. Qdrant and OpenSearch dashboards are wired in for inspection, with on-demand model loading to manage VRAM.

OCR comparator — RTX 5090

Drop an image, watch 4 open-weight OCR models transcribe it side by side — fully local, streaming.

  • Models: GLM-OCR · dots.ocr · DeepSeek-OCR-2 · Chandra OCR 2
  • GPU: RTX 5090 (32 GB, sm_120)
  • Backend: FastAPI + SSE

A local web UI that compares four open-weight OCR models side by side on a dropped image. The four models run on-device and their outputs stream in (SSE) with each model’s inference time. Nothing leaves the machine.

Built for an RTX 5090 (Blackwell sm_120) under WSL2: torch from the cu128 index, SDPA attention (no flash-attn wheels for sm_120), a 28 GB VRAM budget with LRU eviction, and four separate Python environments because the models need mutually incompatible transformers versions.

axolotl for RTX 5090 with vLLM

A patched axolotl Docker image that makes LLM fine-tuning work on the RTX 5090, with vLLM serving.

  • Image: fenyoa/axolotl (DockerHub)
  • CUDA: 12.8 (sm_120)
  • Serving: vLLM + Open WebUI / Gradio

A patched build of the axolotl fine-tuning framework that supports the NVIDIA GeForce RTX 5090 together with vLLM. Published as a Docker image on DockerHub and runnable under Windows 11 with WSL and Docker Desktop.

The workflow is end to end: train a LoRA adapter inside the container, merge it into the base model, then serve the fine-tuned model with vLLM (context capped at 8192 tokens to fit 32 GB of VRAM) and chat with it through Open WebUI or the built-in Gradio UI.

axolotl itself is a free, open-source framework for post-training the latest LLMs — full fine-tuning, LoRA / QLoRA, GPTQ, QAT, preference tuning (DPO, IPO, KTO, ORPO), RL (GRPO) and reward modelling, all driven by a single re-usable YAML config. This fork patches it to build and run on the RTX 5090 (Blackwell sm_120 / CUDA 12.8) and pairs it with vLLM serving. Successfully tested on Windows 11 24H2 + RTX 5090 with an AMD Ryzen Threadripper 7980X.

Ministral-8B-Instruct LoRA fine-tuning

A minimal LoRA fine-tuning pipeline for Ministral-8B on a domain FAQ, judged by an OVH-hosted model.

  • Base: Ministral-8B-Instruct-2410
  • Method: LoRA (TRL SFTTrainer)
  • Service: OVH AI Training

A minimal, scripted LoRA fine-tuning pipeline for Ministral-8B-Instruct, centred on a "Mon Espace Santé" FAQ: train the adapter, merge it into the base, run inference, and validate answers — including a positive-example validator that asks an OVH-hosted gpt-oss-120b model to score each response.

Includes the practical last mile too: hard-coding the system prompt into the chat template after merge, and converting the merged model to GGUF for import into Ollama. Python 3.13 is recommended; training wants a GPU, a Hugging Face account with access to Ministral-8B-Instruct-2410, and (optionally) a Weights & Biases account for reporting.

Fine-tuning GPT-OSS:20B on OVH AI Training

A container to fine-tune the GPT-OSS:20B open model on the OVH AI Training service.

  • Model: GPT-OSS:20B
  • Service: OVH AI Training

A container setup to fine-tune the GPT-OSS:20B open-weights model on OVH’s managed AI Training service — part of a series of experiments on running serious LLM training jobs on rented cloud GPUs.

Glossaries of LLM improvement & alignment methods

Working glossaries of the methods used to improve and align large language models.

  • Form: Glossaries / notes

A set of working glossaries cataloguing the methods used to improve and align large language models — assembled as a reference while running the training and fine-tuning experiments listed here.

Mon Espace Santé — AI assistant

A live AI assistant that answers questions about the French public-health service Mon Espace Santé.

  • Domain: Mon Espace Santé FAQ
  • Status: Live

A deployed AI assistant that answers questions about 'Mon espace santé', the French national health-record service — the production counterpart to the knowledge-injection experiment documented elsewhere on this page.

Can AI design an electronic board, floor to ceiling?

From an oscilloscope photo to a fully-assembled 4-layer board built by JLCPCB — schematic, simulation, PCB, firmware and enclosure, all driven by Claude.

  • Tool: Claude Code · Opus 4.8 (Max effort)
  • Fab: JLCPCB · fully assembled
  • Board: 4-layer · ≤8×8 cm
  • MCU: ESP32
  • Sim: LTspice

A weekend question: beyond programming far faster and better than I do, could AI design an electronic board floor-to-ceiling? I conveniently remembered a project I had abandoned in early 2018 — deporting my building’s intercom — and decided to resurrect it.

The method: I clipped an oscilloscope onto the bare wires that had been dangling in the flat’s hallway for 8 years, and photographed its screen with my iPhone while someone pressed the button in the entrance hall (the same person who, 8 years earlier, had agreed I could leave the wires in place — against my promise to finish the project one day…). I then handed Claude Code (Opus 4.8, Max effort) the photo and, more or less, the prompt shown at the top of the image. It produced everything needed to order the complete board — component selection and soldering, through-hole parts included — from JLCPCB. The order went out that evening.

Why I capped the board at 8 cm per side: simply so I could later ask Claude to generate the STL of an enclosure I would print on my 3D printer, which is limited to 10×10×10 cm.

The sequel — and the end of the story. JLCPCB’s human check caught one of Claude’s mistakes: it had picked the right-angle version of the header strips used to plug in the micro-controller module. Since those are through-hole parts, the JLCPCB engineer assigned to the board immediately understood I would never be able to plug anything in with that shape.

I did not deal with JLCPCB to resolve it — Claude did. Through its Gmail connector, it ran the whole exchange to select a straight, non-angled reference, and got along famously with the engineer on the other side. Claude then handled a second problem: some passive-component references were out of stock, so it found replacements and told me how to update them in JLCPCB’s web interface.

It went to fabrication and I picked up the parcel three days ago. I quickly checked that everything looked correctly soldered (4 layers, double-sided, SMD and through-hole) and tested it right away — only to find the daughter module was not being powered. I understood Claude’s error at once: it had used the wrong pinout for the micro-controller module, mirroring left and right (or top and bottom, same thing).

I pointed it out, and Claude offered on its own to modify the firmware it had already written (the I/O now landed on different GPIOs than planned), then told me how to fix the electrical problem with a flying wire and a snip of the cutters. Everything now works: I printed a 3D enclosure and wrote 5 lines of shell that fire an alarm on my Amazon Echos when someone rings downstairs.

Live AI demos on an RTX 5090 — applications I built, running on models I trained myself.

Lab

Electronics, home automation, drones, soldered in the kitchen.

A running notebook of contraptions. Some replace a €70 part with €15 of components; some let a wristwatch turn on the television; one of them ended a drone's flight with a telnet session.

Touching my watch to switch on the TV

One tap on a smartwatch and, eight relays later across five networks, the TV switches on.

  • Trigger: SmartWatch 2
  • Hops: 8 stages
  • Networks: Bluetooth · Wi-Fi · 802.15.4

One tap on the watch screen sets off a chain of eight stages crossing five different networks before a single infrared LED finally turns the television on.

1 — The SW2 watch reports the screen press to my Galaxy S2 over Bluetooth. 2 — The Galaxy S2 relays the request by HTTP over Wi-Fi to the Apache web server of fenyo.net, running inside a SuSE Linux virtual machine. 3 — Apache runs a CGI script that connects over Wi-Fi to a Wi-Fi range-extender wired to a Raspberry Pi behind the TV; a GPIO pin of that Pi reads a coil wrapped around the TV mains cord, to check the set is not already on (if it is powered it draws current, the coil sees an induced current and the Pi digital input goes high).

4 — If the TV is off, the CGI script connects to a J2EE server (hosted on a Windows machine) running an application able to talk in API mode to an XBee and relay information to every XBee in the flat. 5 — That J2EE server opens a TCP connection to a physical RedHat Linux box, where a small process forwards the TCP stream to a USB port wired to a USB/serial interface driving an XBee coordinator in API mode — the gateway to all the home-automation XBees.

6 — The coordinator relays the remote-control code to an autonomous module next to the sofa, made of an XBee endpoint connected to a microcontroller over an asynchronous serial line. 7 — The microcontroller drives the code onto an I/O output wired to a transistor that pilots an infrared LED. 8 — The TV turns on.

Adding light-bulb control to my home automation

Folding Hue bulbs into a flat that already ran four wireless networks on carefully chosen frequencies.

  • Gift: Philips Hue pack
  • Bridge: Ethernet ↔ ZigBee
  • Band: 2.4 GHz

It started at Christmas with a Philips Hue pack: three bulbs and a bridge between a wired Ethernet network and a pervasive ZigBee network of bulbs — labelled, as Philips puts it on the back, a Zigbee IP Bridge.

I already ran four wireless networks at home, with center frequencies specifically chosen for good channel rejection between them: Wi-Fi 802.11g 'ivrynet' (2nd floor, from my FreeBox, centered at 2.422 MHz); 'ivrynet extended' (1st floor, via a Wi-Fi repeater, same density since consumer repeaters carry a single radio); 'ivrynet extended 2' (dedicated to Apple AirPlay audio/video streaming, bridged over PLC, centered at 2.462 MHz to avoid collisions between streaming and browsing); and a 802.15.4 network of XBee Pro modules (one coordinator, several endpoints) for the window shutters and multimedia devices, centered at 2.440 MHz to dodge the Wi-Fi.

The trouble: Hue's ZigBee network layer sits on the same 802.15.4 physical layer as my XBee Pro — DSSS with BPSK modulation in the 2.4 GHz band — and the Hue system offers no way to pick a center frequency. As my spectrum analysis showed, my Wi-Fi and 802.15.4 fields stayed clear of each other, but the Hue bridge stubbornly parked itself at 2.425 MHz, right inside my Internet box band, no matter how many times I power-cycled it. Luckily it did not interfere with the dedicated streaming ESSID — but it really should run an energy scan before choosing a channel.

To find the channel it had grabbed, I used an XBee Pro module to run an active scan: it discovered my own 802.15.4 network, so the other one had to be Hue. I confirmed it by firing many status requests at the bulbs through the Hue RESTful/JSON API while running an energy scan — energy showed up only on the identified channels.

The bulbs are now part of the whole system: I can switch them from my watch, from the DECT phones (dial 8 to toggle), or from the web interface. Two 802.15.4 bridges sit side by side at home — the XBee Pro (USB ↔ 802.15.4) and the Hue module (Ethernet ↔ ZigBee).

Electric window-shutter transcoder

A wireless-to-wireless bridge letting my XBee network drive the proprietary radio of our window shutters.

  • In: XBee / 802.15.4
  • Out: Bubendorff RF
  • Schedule: crontab (sunrise/sunset)

This is a wireless-to-wireless interface for our Bubendorff electric window shutters: a transcoder between the low-power XBee / 802.15.4 transmission protocol and Bubendorff's proprietary wireless automation protocol. The shutters open and close on their own, driven by a crontab that computes sunrise and sunset times.

The prototype worked well, so I made a production release and uploaded the physical design files to a PCB manufacturer in China (three weeks' wait). Production version 2 adds an internal buzzer — installed in the bedroom, it turns the whole thing into a low-cost alarm clock based on a crontab.

Playing with magnetic fields: is the TV on?

An analog probe that reads the magnetic field of the TV mains current, so scripts know whether it is already on.

  • Senses: Mains AC field
  • To: Raspberry Pi GPIO
  • Power: ≈1.5 W

My scripts can switch the TV on or off, set the channel and adjust the amplifier — but to do it safely they must know the TV's current power state: if the set is already on, sending the 'on' IR code would switch it off instead. So I designed an analog module that probes the magnetic field generated by the alternating current the TV draws from its wall outlet. The signal feeds a digital input on the Raspberry Pi GPIO, then travels to the server over Wi-Fi.

Tuning note 1: the 990 Ω resistor can be adjusted to set the current-detection threshold — at home I use 800 Ω, and the whole module draws about one and a half watts.

Tuning note 2: to reject high-frequency interference that could make the system wrongly report the TV as on, you must ground the module to earth, tie the TV earth to the outlet earth, and adjust the (non-polarized) capacitor wired in parallel with the transformer output coil. At home a 470 nF X7R capacitor filters above 6 kHz; a 10 µF one would filter above 300 Hz.

First week of statistics collected this way: 20 h 41 m of television.

Universal infrared remote control

A home-made IR receiver/transmitter to run the TV and hi-fi from a DECT phone or a web page — across three generations.

  • V1: USB module
  • V2: XBee + Asterisk PABX
  • V3: Web interface

A universal infrared receiver/transmitter I built to manage the TV and other multimedia devices from my DECT phone.

Version 1 was a simple USB-driven module. Version 2 added a wireless XBee module to connect the infrared box to my Asterisk PABX, so I could fire IR commands from the DECT phones.

Version 3 added a web interface. The 'TNT', 'Apple TV' and 'DVD' buttons launch advanced scripts that switch the ADSL TV box, the Apple TV or the DVD player on and off, adjust the hi-fi amplifier volume, and select the right SCART or HDMI input. The 'Loop' and 'Stop' buttons cycle through a set of TV channels (five seconds each), the 'Volume' button sets the amplifier level, and the channel names change the current channel on the ADSL TV box.

Hacking an infrared key transmitter

The parking remote only sent its 24-bit secret three times per press, so I cloned it to send it continuously.

  • Original: Valeo · Philips OM1058T
  • Clone: PIC16F877 + IR LED
  • Key: 24-bit secret

I often had trouble opening our parking door at home: the infrared key transmitter never worked reliably. Built by Valeo around a Philips OM1058T chip, it transmits its 24-bit secret key only three times when you press the button — not enough. To fix it, I needed to build a similar module that sends the key continuously.

First I recovered the secret key with a phototransistor and my Tektronix oscilloscope. Then I made a clone around a general-purpose microcontroller and an ordinary consumer infrared LED. I designed a small board integrating a Microchip PIC16F877 microcontroller, an asynchronous serial interface and an I/O extension port, uploaded the physical design files to a PCB manufacturer in China, bought the parts from a local reseller, and soldered the whole thing in the kitchen.

Voice/data link between intercom and Raspberry Pi

A voice-and-data bridge between the building intercom and a Raspberry Pi — and a €70 power supply replaced by €15 of parts.

  • Ring detect: discrete → GPIO
  • PSU: LT1054, <€15
  • Filter: 10 V RMS @ voice band

A voice-and-data link between our building intercom and a Raspberry Pi. I added an intercom-ring detector feeding a Raspberry GPIO input, built entirely from discrete components.

Cost-cutting operation: I replaced my dual regulated power supply — €70 incl. VAT at Conrad — with a build costing under €15 incl. VAT, based on an LT1054 (bought for €7 incl. VAT a unit at RS-Online). Net saving: more than €55, tested OK on the intercom assembly. The dual PSU and the intercom/Raspberry adapter ended up on the same board — the equivalent of a Bose speaker, packed onto one plate.

I simulated the active filter of the intercom ↔ Raspberry interface (10 V RMS across the voice frequencies) before building it, and analysed the intercom line to get the levels right.

Wideband spectrum analysis

Mapping the invisible: DCS and UMTS cells, the microwave oven, the home EM environment — and finding a rogue emitter with folded kitchen foil.

  • Range: 15 MHz – 2.7 GHz
  • Targets: DCS · UMTS · 2.4 GHz

I deal a lot with high-frequency electromagnetic fields, so to make my wireless systems behave I use a wideband spectrum analyzer covering 15 MHz to 2.7 GHz. In the DCS range I took two measurements at two locations in the same building, which sits near a DCS antenna: the field intensity at the first spot is about thirty times the one at the other.

The same analyzer maps the electromagnetic environment at home, lets me check mobile UMTS coverage near a telecom pylon, and reveals that my microwave oven sits at about 2458 MHz.

A field trick for direction-finding: starting from a whip antenna (equal gain all around its axis), fold a sheet of kitchen aluminium foil in four and use it as a reflector. Turn on the spot, and when the signal peaks the emitter is in front of you — handy for tracking down whatever is spitting out −40 dBm. The only catch is the passers-by wondering whether you work for 'the Services'.

A thermal camera to overclock my PC

A thermal camera to overclock the PC properly — and find out exactly what runs hot inside the case.

  • Ambient: 23 °C
  • Chipset: +21 °C over ambient
  • SSDs: barely warm

I moved to a thermal camera to overclock my PC correctly. Ambient temperature: 23 °C. The regulated extraction fans do their job — between the case open and closed, the top fans' output flow rises only 3 °C (from 29 to 32 °C).

On the motherboard side, the hottest spot (excluding the processor) is the heatsink over the big chipset: 54 °C, i.e. 21 °C above ambient. The hard drives sort themselves out by type: the mechanical ones run hottest — the 7200 rpm 2.5″ at 34 °C, then the 5400 rpm 3.5″ — while the two SSDs sit barely above room temperature.

Overclocking my PC

A 2.5-year-old PC pushed to a stable 4.8 GHz.

  • CPU: Core i5 3570K
  • Clock: 4.8 GHz

I boosted my 2.5-year-old PC: a Core i5 3570K running at 4.8 GHz.

Playing with magnetic fields

A demo board for a Hall-effect sensor — switching a LED with a magnet, then counting helicopter RPM.

  • Sensor: TLE4905L (unipolar)
  • Driver: 2N2369A

A basic demonstration board for the TLE4905L unipolar magnetic-field sensor: bring a magnet close and it switches a LED on or off. The LED is driven by a 2N2369A transistor.

The same board, repurposed, counts the RPM of an RC helicopter rotor.

Electrical characteristics of a green LED

An automatic curve-tracer for the small LEDs I keep using, from a function generator, a multimeter and shell scripts.

  • Source: Centrad GF 265
  • Meter: APPA 106
  • Glue: shell scripts

Since I keep using this kind of small LED on my boards, I wanted to know its exact electrical characteristics. So I connected a function generator (Centrad GF 265) and a multimeter (APPA 106) to a PC over serial ports and wrote an automatic electrical-characteristics analyser out of simple shell scripts.

USB charging time

A board that watches a USB device power draw on an LCD and logs it to a serial port.

  • MCU: PIC24F
  • Base: Microchip dev board + daughter board
  • Output: LCD + serial log

My USB charging-time module — built on a PIC24F, a Microchip development board and a daughter board designed specifically for this project — monitors the power consumption of a USB device on an LCD screen and logs the results to a serial port.

3D printing and finite-element analysis under 10 N

A wall bracket designed, then stress-tested under 10 N with the finite-element method before printing.

  • Load: 10 N (1 kg)
  • Method: Finite elements

I designed a kind of wall bracket assembled from several copies of one part, and used the finite-element method to simulate a stress test under 10 newtons (1 kg) before printing a single gram of filament.

3D-printed parts and mechanisms

Brackets, boxes, clamps, mounts and one rescued gear — the steady output of the printer.

  • Theme: Print what you cannot buy

A running collection of small designs printed to solve one specific problem each — from cable management to enclosures, mounts and repairs. A highlight is the XBee-Pro two-way remote command: 2 analog inputs (potentiometers), 4 digital inputs (push buttons), 4 digital outputs (LEDs) and a buzzer, over IEEE 802.15.4 at 2.4 GHz, 1.2 watts, with a J2EE controller running on FreeBSD.

Repairs and restorations

An aluminium helicopter shaft, a broken Switchbot, a multimeter case — brought back from the dead.

  • Motto: Repair rather than replace

Three hours' work: replacing the original inner shaft of an RC helicopter with an extended (+1.5 cm) aluminium one, and swapping out a broken engine.

Other rescues along the way: a broken Switchbot brought back to life, and a multimeter case repaired by printing the missing part.

Parrot Skycontroller and Bebop drone

After too many helicopter crashes, a GPS-backed quadcopter with a 2 km link and a back-home button.

  • Drone: Parrot Bebop
  • Link: Skycontroller, 2 km
  • Safety: GPS back-home

This year I gave up on helicopters — too much breakage, too hard to steer with all the wind around here. My first flight with the new immersive-view quadcopter was a Parrot Bebop (a quadcopter with an integrated camera) paired with a Skycontroller: 2 km range, with live image and the Bebop's position in real time. Both carry a GPS, so pressing the 'back home' button brings the quadcopter back to where the pilot is standing.

I bought the extended-range remote (the Parrot Skycontroller) specifically to take pictures from the sky, and ran a little experiment with that extended-range transceiver.

Reading a drone boot messages over telnet

A drone with no Wi-Fi encryption, running a DHCP server and a telnet that drops you straight into a shell.

  • Wi-Fi: no encryption
  • Service: DHCP + telnet → shell

I recovered my drone's boot messages over a telnet session: there is no Wi-Fi encryption, the drone acts as a DHCP server, and telnet drops you directly into a shell. A few well-placed kills later, it is on the ground — or somewhere else.

A Dell R510 from a broker, in a closet

A Dell R510 from a broker in Limoges — €12k list, €350 paid — installed in a closet.

  • Server: Dell R510
  • List price: €12,000
  • Paid: €350

I picked up a Dell R510 server from a broker I came across by chance in Limoges — €12,000 at the manufacturer's list price, €350 from the broker — and installed it at home in a closet.

Home electrical-consumption monitoring

Because you cannot improve what you do not measure.

  • Scope: Whole home

I installed whole-home electrical-consumption monitoring — because you cannot improve what you do not measure.

A WASD V2 88-key custom mechanical keyboard

An 88-key custom board with Cherry MX Brown and dampeners — quiet enough to type while Agnès sleeps.

  • Board: WASD V2 88-key ISO
  • Switches: Cherry MX Brown + 0.2 mm dampeners

My home keyboard: a WASD V2 88-key ISO custom mechanical board. For years I had been looking for an 88-key layout — I never use the numeric keypad, but I really need the PageUp/PageDown/Insert/Home/Delete/End cluster. Since I mostly work at night while Agnès wants to sleep, I chose Cherry MX Brown switches and added 0.2 mm sound dampeners.

I designed a custom three-colour layout (red keys for Esc and Enter, grey for the special keys, black for letters and numbers) and asked for a Ubuntu logo on the system key instead of the Windows one. It is far quieter than my old Logitech and frees up real desk space — which is very, very cool. It was rather expensive ($175 before VAT and shipping, plus €55 of customs duty and an eye-watering $75 of UPS shipping for such a small parcel). Very happy with it so far.

Comparing terrain (altimetric) profiles

Estimating the horizontal step and vertical accuracy of three elevation models.

  • Best: Géoportail 3D

Géoportail 3D turns out to be far better than the open-data BDAlti at 75 m. From these measurements I tried to estimate the horizontal step and vertical accuracy of the 3D models used at this location.

A leap second, live

A leap second, captured live on an iPad.

  • Event: Inserted leap second

A small curiosity: the inserted leap second, captured live on my iPad.

Commodore 64 revival

The original Commodore 64 — still in daily use 25+ years on, plugged into the SCART of a 40-inch HD-Ready TV.

  • Machine: Commodore 64 (1982)
  • Graphics: VIC-II MOS 6569/8569 PAL
  • Display: Samsung LE40R86BD · 40″
  • Peripherals: 1541 drive · MPS 801 printer

After starting to program in 1979 on a PET CBM 4032, I bought a Sinclair ZX-81 in 1980 and finally sold it in 1982 to buy this wonderful Commodore 64 — and I am still using it regularly more than 25 years later.

The display: it is connected to the SCART input of our Samsung 40-inch HD-Ready flat TV (LE40R86BD). Thanks to the internal VIC-II MOS 6569/8569 PAL graphic chip, the fine 320×200 resolution is totally compatible with the 1366×768 pixels of the LCD panel.

The devices: I connected the original peripherals — tape recorder, Commodore 1541 disk drive and MPS 801 printer. Unfortunately I could not find any of those single-sided 170 kilobyte 5.25″ floppies.

Daily programming: Agnès uses this state-of-the-art computer very often — to manage our bank accounts, print recipes, letters and so on. And yes: it works!

A major European airport Wi-Fi with no client isolation

  • Where: Major EU airport
  • When: 2026
  • Expected: Private VLAN / client isolation
  • Found: Full L2 visibility

Years ago I published an App Store app to explore the local network your device connects to — broadcasts, Bonjour, an nmap-equivalent, and more. Back then (before vibe coding) it took me an enormous amount of time to build, especially since I knew nothing about Apple’s development environment.

I assumed that “private VLAN” (client isolation) was, by now, standard in the hotspots of any serious operator — not necessarily in every hotel, but at least in public venues. This morning, arriving at a major European airport on my way back from holiday, I decided to check this assumption, which makes my app a little obsolete.

What a surprise: everyone sees everyone! In short, a disgrace in terms of securing the service, in 2026. The video below shows my scan.

Coding, on a TGV, the game I had dreamed of since 1982

  • Where: TGV to Paris · SNCF Wi-Fi
  • Tool: OpenAI API (gpt-4o)
  • Runtime: Swift Playgrounds (iPad)
  • Cost: ≈ €0.01
  • Time: 15 minutes

Fifteen minutes of my Sunday, on the train back to Paris after a weekend in Boulogne-sur-Mer to visit Nausicaá, the largest aquarium in Europe. In my old TGV, with only my iPad and the Wi-Fi “offered” by the SNCF, a thought crossed my mind: what if I finally stopped programming?!

So I pointed Safari at OpenAI’s portal (the makers of ChatGPT), which lets you use their AI API without a subscription — billed simply per token, far cheaper than the subscription even for standard daily use. I described, in French, the functions I wanted for the game I had dreamed of writing ever since I was given a Commodore 64 in 1982.

I chose gpt-4o (the most effective for generating code) and told the AI to produce the program in Swift so it could run in Swift Playgrounds on an iPad — Apple’s free app for teaching programming: no Mac needed, you load it on an iPad, write Swift, and it compiles and runs right on the tablet.

I pasted the source the AI proposed into Playgrounds and played my first game! So this weekend I created a game in 15 minutes, compiled and deployed it to a tablet, then played it (and lost). It cost me about one cent of a euro.

I had waited 42 years for that day: finally programming the game that fascinated me back then, and still does today. The world of software development is going to change radically, very very soon! The post below shows the code and one of my first games.

Extreme sports — a phone on the landing gear

A 188 g Galaxy S2 strapped to the landing gear of an RC helicopter — flight, picture-in-picture, and crash.

  • Aircraft: E-sky Big Lama
  • Payload: Galaxy S2 · 188 g

I strapped my Samsung Galaxy S2 to the landing gear of my E-sky Big Lama RC helicopter. The main video carries a picture-in-picture shot taken from the phone during the same flight — and crash. At 188 g with its cover, the phone is very heavy for an RC helicopter.

Roller — slalom demonstration

A demonstration of slalom — away from the soldering iron, for once.

  • Discipline: Freestyle slalom

Not everything happens at the workbench: a demonstration of roller slalom.

Design

Logos, flyers, booklets and maps — drawn by hand in Corel, Illustrator and Visio.

Before the soldering iron there was the cursor: identities for doctoral schools, printed plaquettes, campus and network maps, and the diagrams that explain a machine to itself.

Logo design — EDITE de Paris & EDDV

Two academic identities: the EDITE de Paris doctoral school, and the EDDV.

  • Tools: CorelDraw · Illustrator · Photoshop
  • For: EDITE · EDDV

I designed this logo for EDITE de Paris (École Doctorale d’Informatique, Télécommunications et Électronique de Paris), using Corel Draw and Adobe Photoshop.

And this one for the EDDV, using Adobe Illustrator and Adobe Photoshop.

Flyers for the Eliane & Isa Show

Show flyers designed with the help of Agnès Lefranc, in Adobe Photoshop.

  • Tool: Adobe Photoshop
  • With: Agnès Lefranc

I designed these flyers, with the help of Agnès Lefranc, for the Eliane & Isa Show, using Adobe Photoshop.

Map of Jussieu

A RATP map of the Jussieu campus, extended with new buildings and numbers.

  • Base: RATP map

I modified a map of Jussieu designed by the RATP: I added some new buildings (31-41, the gymnasium, the Maison de la pédagogie), the building numbers, and so on.

Web server design

A handful of web servers built over the years — this one included.

  • Count: several

Over the years I designed a number of web servers: this very home page; some pages of the main EDITE server; the data-processing services server of EDITE (in Flash); the ENST alumni server; the MPC parallel-computer project server; and the Eliane & Isa show server (with A. Lefranc). Several of them are now closed.

Writing

A book, a thesis, and the research around them.

Published in print, defended at university, and then mostly given away under Creative Commons.

Peer-reviewed papers — mostly on the MPC parallel computer and its high-speed communication protocols — plus an early Internet primer.

Conception et réalisation d’un noyau de communication bâti sur la primitive d’écriture distante

MPC-OS — a zero-copy communication kernel built on the remote-write primitive, for Gigabit clusters of PCs.

  • Defended: 5 July 2001 · Jussieu
  • Where: UPMC
  • Network: 1 Gbit/s wormhole DMA
  • Used by: GEC Marconi · Parsytec

My doctoral thesis — « Conception et réalisation d’un noyau de communication bâti sur la primitive d’écriture distante, pour machines parallèles de type grappe de PCs ». I started it on parallel computing in November 1995 and defended on Thursday 5 July 2001 at 10:00, room 203-205, Bâtiment 41, Campus Jussieu, 4 place Jussieu, 75005 Paris.

It presents the design and construction of MPC-OS, a communication kernel built on the remote-write primitive and dedicated to parallel computers made of clusters of workstations: a stack of protocols implemented inside the Unix kernel, available both to user-level processes and to the OS’s own internal modules.

Based on a simple DMA hardware primitive for Gigabit interconnect networks, MPC-OS provides value-added services — communication over virtual channels, reliable transmissions, data exchange between virtual-memory areas, and memory management that preserves the integrity of the communication buffers. To get maximum efficiency every service is zero-copy, which was the major difficulty of the work.

Dynamic resource allocation is externalised to a distributed manager, built on a multi-threaded Object Request Broker (ORB) I designed specifically for MPC-OS.

After a detailed survey of the software performance, I approached the reliability problem in a new way: a probabilistic model of fault-coupling shows that, under a few basic conditions, an elementary correction protocol can deliver good performance and significant reliability at the same time.

MPC-OS went on to run on several MPC clusters spread across French universities, enabled optimised ports of the PVM and MPI parallel-programming environments to the MPC machine, and was used by manufacturers (GEC Marconi Aerospace Systems and Parsytec Computer) to validate hardware built from the same components as the MPC platform. The full BSD-Unix-based OS source — about 40,000 lines of mixed kernel / user-level C, C++ and Perl — is available below, along with the stochastic results established during the thesis.

Keywords: parallel computer, cluster of workstations, programming environment, remote write, reliability, memory management, dynamic resource allocation.

An introduction to SNMP v2

After writing SNMP managers and agents, an introduction to the second version of SNMP.

  • Format: PDF

After programming a number of SNMP managers and agents, I wrote an introduction to SNMPv2, the second version of the Simple Network Management Protocol.

A little theorem in algebra

A proposition in algebra I obtained — and was never 100% sure of, until a proof arrived in 2002.

  • Field: Algebra

I am very interested in mathematics, especially algebra. From my small investigations I obtained a proposition for which I was never 100% sure of my proof — and invited counter-examples or a proof by mail.

Note (2002): thanks to G. Legrand, who found a proof, there should be no counter-example.

Raccorder son réseau d'entreprise à l'Internet

Book · Eyrolles, 1997 · CC, 2006

A book on connecting corporate networks to the Internet — first in print, then released under Creative Commons. © A. Fenyo, F. Le Guern, S. Tardieu.

Read

Papers

  • La machine MPC — Pierre David, Jean-lou Desbarbieux, Alexandre Fenyö, Alain Greiner, Jean-Jacques Lecler, Frédéric Potter, Vincent Reibaldi, Franck Wajsburt, Belkacem Zerrouk — Calculateurs Parallèles, Réseaux et Systèmes répartis (réseaux à haut débit de stations pour le support d’applications parallèles et réparties), vol. 10 / no 1, February 1998.
  • Le fonctionnement de l'Internet, architecture, routage — Tribunix no 57, September/October 1994.
  • Noyau de communication sécurisé pour la machine parallèle MPC — Alexandre Fenyö, Pierre David, Alain Greiner — Proceedings of RenPar’10, Strasbourg, France, June 1998.
  • SmartHSL: An Evaluation Board for the IEEE 1355 Technology — Jean-Jacques Lecler, Alexandre Fenyö, Alain Greiner, Frédéric Potter — European Multimedia, Microprocessor Systems and Electronic Commerce Conference (EMMSEC’97), Florence, Italy, November 1997.
  • The MPC Parallel Computer: Hardware, Low-Level Protocols and Performances — Amal Zerrouki, Olivier Gluck, Jean-lou Desbarbieux, Alain Greiner, Franck Wajsburt, Alexandre Fenyo, Cyril Spacevski — Proceedings of the 12th International Conference on Parallel and Distributed Computing and Systems (PDCS’2000), Las Vegas, USA, November 2000.
  • Protocol and performance analysis of the MPC parallel computer — O. Gluck, A. Zerrouki, J.-L. Desbarbieux, A. Fenyo, A. Greiner, F. Wajsburt, C. Spasevski, F. Silva, E. Dreyfus — Proceedings of the 15th International Parallel and Distributed Processing Symposium (IPDPS’2001), San Francisco, USA, April 2001.

Tips & tricks

Notes I keep so I never solve the same problem twice.

Short, practical write-ups from the bench — a driver tweak that multiplies throughput by ten, downstream QoS that “cannot” be done, a 60 A relay driven by a micro-controller, a microscope on an SSOP-28 pad. Pick one to read it.

Improving network performance ×10

From 67 to 650 Mbit/s on a Realtek 8168B.

  • Hardware: Realtek 8168B GbE
  • OS: Windows

A few tips to configure a Realtek 8168B gigabit Ethernet controller and multiply throughput by about ten.

QoS on downstream Internet IS possible

Shape inbound traffic with a Cisco SMB switch, RMON, an aggregate policer and a syslog daemon.

  • Gear: Cisco Small Business switch
  • Status: In production at home

People will often tell you it is impossible to shape traffic coming from a remote router that has no QoS rules — typically the case with consumer DSL or fibre boxes. Others sell advanced QoS appliances with virtual probes; others still claim a Linux box does it best.

I cannot imagine using a Linux box to switch or route packets across several interfaces at 1 Gbit/s — a router should be specialized to route, and nothing else, to keep latency very low. So here is how to implement downstream QoS with a Cisco Small Business switch instead.

It has worked correctly at home for months to manage video traffic to my set-top boxes.

Driving a 60 A latching relay with a micro-controller

Power dozens of computers on and off at once — the FenyoBox.

  • MCU: Microchip PIC16F876
  • Relay: HFE9 60 A dual-coil

A few years ago I had to manage a dozen servers in a room whose air-conditioning kept failing — during each incident the temperature rose to about 60 °C in ten minutes. So I built a little box able to stop the big UPS, which meant driving a double-coil 60 A latching relay (HFE9 / JE9 12-HS). The whole computer room could then be shut down and restarted at once: the FenyoBox.

The command part is built around a Microchip PIC16F876 micro-controller connected to a modem through a serial port (via the well-known MAX232N, a +5 V RS-232 driver). The power part for each coil uses a very low-cost 2N2369A transistor driving a CNY17 opto-coupler with a 2 W ceramic resistor in series for enough output current; the opto-coupler output drives the coil.

Years later the relay finally failed. Repairing it revealed how poorly the original was designed — no rectifier to absorb the ~200 V coil kickback I measured, power lost in the opto-couplers, overloaded transistors. So I redesigned the command part with both inputs driven directly by a micro-controller. The difficulty: the two coils share the same negative terminal and the working voltage is higher than an MCU can drive directly.

Home networking

One apartment, a dozen network types, mapped at layer 2.

  • Scope: One apartment
  • View: Layer-2 map

Home networking can be surprisingly complicated nowadays, given how many kinds of network you can find at home. Here is my home layer-2 map.

It includes Fast- and Giga-Ethernet wired links; internal and external POTS links (IPBX to DECT base; ADSL box to ISP); a wireless DECT network; several Wi-Fi networks (guests, two for home computing, one dedicated to multimedia streaming) with remote sensors such as a Raspberry-Pi TV power sensor; PLC modules bridging the streaming access point; a ZigBee PAN for light bulbs; and a 802.15.4 PAN for window shutters and infrared remotes.

Magnifying a pad from a small SSOP-28 package

A digital microscope on a tiny package — about 2.5 µm per pixel.

  • Tool: DigiMicro Lab5.0
  • Scale: ~2.5 µm / pixel

To test my digital microscope (a DigiMicro Lab5.0 from DNT) I photographed an FT232RL USB-to-UART converter in an SSOP-28 CMS package. As you can see, one pixel is about 2.5 µm wide.

A companion experiment compares pixel shape and density on a Samsung Galaxy S2 and an Apple iPad 2: about 192 µm per pixel on the iPad 2 versus only 116 µm on the S2 — and quite different shapes.

Very low-cost 20 MHz function generator for ham radio

A few discrete parts — and a 33-year-old Tektronix that beats a modern scope.

  • Parts: 2× BFR96TS, 7 caps, 3 coils
  • Output: 20 MHz
  • Base gen: Centrad GF265

I had no money for the state-of-the-art DDS function generator reaching 20 MHz that I needed to test my HF amplifier. So I bought a low-cost medium-frequency DDS generator instead (a Centrad GF265, up to 5 MHz) for low- and medium-frequency experiments, and built a few simple discrete analog components to reach a 20 MHz signal.

The board has two parts: a Colpitts oscillator followed by a power amplifier. Each part needs an RF transistor, so I used two BFR96TS NPN RF transistors. As the schematic shows, getting to 20 MHz took only 2 transistors, 7 capacitors, 3 coils and a few resistors.

I then used this generator to compare my 21st-century 2×25 MHz Velleman PCS500 digital oscilloscope with a very old Tektronix 465 2×100 MHz analog scope that left the factory in 1975. The 33-year-old Tektronix was excellent next to the new one: its trigger was harder to fine-tune but finally gave a very stable display — the Velleman never did.

IP phone to analog phone interface circuit

Keep your old modem, DECT phone or Minitel alive behind an IP phone.

  • Use: Modem · DECT · Minitel
  • IP phone: Alcatel 4028
  • Tested with: Logicom Vega 200 DECT
  • Core: 600:600 Ω transformer · UA741

Your company has just handed you the wonderful, state-of-the-art IP phone you and your colleagues had been waiting months for. You are finally stepping into the 21st century — and rightly proud of it. But something is wrong: your modem, your Minitel and your wireless DECT phone do not work anymore. Of course, in the 21st century nobody imagines those deprecated technologies could still be useful to anyone…

Be careful — this story could happen to you, as it just happened to me. But do not worry: here is the workaround. I call it my IP-phone-to-analog-phone/modem audio interface circuit — or, if you prefer, the "back-to-the-20th-century" audio interface circuit. At work I connected my 19 € analog DECT (a Logicom Vega 200) to an Alcatel 4028 IP phone through it.

The module is based on a hybrid-transformer circuit (schematic below). It taps the IP phone’s handset speaker and microphone lines and couples them to the analog device.

A side story — the Sound Blaster Extigy transfer function: while building this interface I used my Creative Labs Sound Blaster Extigy sound card as a function generator. I ran into weird effects and realized the headphone output had a poor transfer function, which I plotted with my APPA 106 multimeter. After weeks of bad dreams about that strange curve, I suddenly realized one night that it was obviously a Head-Related Transfer Function (HRTF) — the images below compare my measurement with a standard HRTF.

Split tunneling with Cisco

Enabling split tunneling with the Cisco IPsec VPN Linux client — even when the concentrator forbids it.

  • Client: vpnclient-linux-x86_64-4.8.00.0490-k9
  • Platform: Linux kernel module
  • Patch: one line

Enabling split tunneling with Cisco IPsec VPN client software on Linux is always possible — even if it is forbidden by the VPN concentrator.

Split tunneling on the client side of a VPN tunnel is a potential security flaw: viruses, for instance, can propagate easily from the public client LAN to the private internal area at the other end of the tunnel. On Cisco routers and VPN concentrators, the client IPsec software is told by the concentrator whether or not to enable split tunneling, and the default concentrator configuration is to disable it on the client host.

Since this policy is only enforced by the client software, a VPN administrator should not rely on the concentrator configuration. One might think the client software is hard to modify, but it is not: for technical reasons related to the many Linux kernel versions in circulation, Cisco systematically ships the sources of the kernel module inside the vpnclient Linux distribution. Only the user-space daemon is binary-only — and although it is the daemon that decides whether to enable split tunneling, it relies on the kernel module to apply that policy. So you only need to modify the kernel module sources to enable split tunneling even when the daemon does not want it. In fact, adding a single line to the kernel module sources is enough.

The patch (vpnclient-linux-x86_64-4.8.00.0490-k9.diff) enables split tunneling on a client host even when the concentrator uses the default configuration. It assumes you have two physical Ethernet boards, eth0 and eth1; that eth0 is on the path to the VPN concentrator (e.g. the default gateway is connected to eth0); and that eth1 is connected to the hosts you want to keep reaching while the VPN is up.

To use it, just run "ifdown eth1; ifup eth1" right after bringing the VPN up. Any host that is not on eth1 will be reached through the VPN tunnel, and hosts on eth1 will be reached directly.

Modelling IEEE Spanning Tree protocols with a UML class diagram

A class diagram untangling the dependencies across the STP family.

  • Notation: UML class diagram
  • Standards: IEEE 802.1

Spanning Tree and the related protocols produced by the IEEE 802.1 working groups are defined with plenty of cross-references. To really understand the dependencies between them, I drew a UML class diagram that captures those relationships across the latest revisions of the documents.

The classes in the diagram are: 802.1w-2001 (Rapid Reconfiguration of STP, supplement to 802.1D-1998); 802.1s-2002 (Multiple Spanning Trees, supplement and amendment to 802.1D-1998); 802.1Q-2003 (Virtual Bridged LANs); 802.1D-2004 (MAC Bridges, revision of 802.1D-1998 incorporating 802.1w — itself an amendment of 802.1D-1993); MSTP (Multiple Spanning Tree Protocol); GARP (Generic Attribute Registration Protocol); GMRP (Generic Multicast Registration Protocol, used by GARP); and GVRP (GARP VLAN Registration Protocol).

Some manufacturers, like Cisco, introduced proprietary protocols solving the same problems as the standard IEEE 802.1 ones — PVST, PVST+, Rapid-PVST — but you will not find them in this class diagram.

Changing the SCSI target ID of a disk on a Sun SPARCstation 4 or 5

Changing the SCSI target ID of a disk on a Sun SPARCstation 4 or 5 — with no jumpers.

  • Hardware: Sun SPARCstation 4 / 5
  • Disk: Quantum Fireball 1080
  • Target ID: 3 → 5

Problem — the disk shipped in a Sun SPARCstation 4 or 5 answers to SCSI target ID 3, and there are no jumpers on it to change that configuration. So if you want to add such a disk to another SPARCstation that already contains one, both disks share target ID 3 and conflict.

Solution — first find the model of your disk, usually written on a label on its back side (here, a Quantum Fireball 1080), then find its technical datasheet (e.g. by searching the model on the web). The datasheet gives the location of the target-ID jumpers A0, A1 and A2.

On Sun disks the pins for these jumpers are often not fitted, but the connectors are present on the disk board — so you can mimic the presence of a jumper by wiring the corresponding connectors (A0 & A2 in our example). To reach them you usually first remove the screws fixing the plastic piece surrounding the disk.

More precisely, you can change the target ID from 3 to 5 by wiring the two connectors corresponding to jumpers A0 & A2 — this can be done by soldering them. Then install the disk on one of the SCSI connectors of your SPARCstation. To check that the change took effect, enter the boot PROM monitor (press STOP-A during boot) and type probe-scsi: it lists the target IDs of all the SCSI devices on your system.

Warning — this solution is given without any warranty of success, nor of harmlessness to your hardware.

Motorized camera controlled by the telephone

Drive a camera from a phone line to check on the pets from the office.

  • PBX: Asterisk (PSTN)
  • MCU: Microchip PIC16F876
  • Serial: RS-232-C · MAX232N
  • Power: L293D + SN7416
  • Actuator: Stepper motor

I lodge a rotating cast of pets at home (a cat, a chinchilla, hamsters). Each time I tried to phone one of them I could never understand the reply — I never managed to teach them any human language. So I built a motorized camera controlled by the telephone to watch over them from the office.

The system has three parts: 1) a private PBX based on Asterisk — a Linux PC connected to the PSTN that, on an incoming call, converts the DTMF tones into commands sent over an asynchronous V.24 (RS-232-C) interface; 2) an electronic box based on a micro-controller that receives those commands over V.24 and drives a stepper motor; and 3) a USB camera mounted on the stepper, broadcasting to the Internet.

Command part — a Microchip PIC16F876 micro-controller connected to the Asterisk PBX through a serial port, via the well-known MAX232N (a +5 V-powered RS-232 driver). Power part — a quadruple half-H driver (Texas Instruments L293D) driven by four inverters packaged in an SN7416.

Software — the PIC assembler code is provided below. In the Asterisk dial plan (extensions.conf) you add the left and right actions; in this example, pressing 7 and 8 rotates the camera left and right. Those shell scripts call /bin/stepper, built from stepper.c.

Galleries

About

An engineer, a geek, and a protector of slightly confused animals.

Engineer from Télécom Paris, Ph.D. from UPMC. By day, Network & Security IT. By night — and I mostly work at night, quietly, because Agnès would like to sleep — I build, measure, solder, fly and break things.

It started in 1979 on a Commodore PET CBM 4032: a MOS-6502 at 1 MHz, 16 KB of RAM, and a BASIC interpreter in ROM. Little games and prime numbers. The hardware got faster; the habit never left.

At home, a rotating cast of pets — a cat, a chinchilla, hamsters. I once tried, and failed, to teach them any human language, so instead I built a motorized camera I can drive from the telephone to check on them from the office.

Career

  • Network & Security IT — Assurance Maladie · today
  • Engineer — Bull
  • Courses & training — Sun Microsystems — Sun Formation France
  • Engineer — EUnet
  • Ph.D. thesis — UPMC — Sorbonne Université
  • Engineering degree — Télécom Paris (ENST)

Find me

Unpacking...