I want to dual-boot Microsoft Windows 7 and FreeBSD. Since the FreeBSD boot manager will be overwritten when installing Windows (I wonder if this will ever change. Probably not. OS evangelism aside, this is one of the things that truly sucks about a Windows installation), I decided to use the Microsoft Windows 7 boot manager to boot FreeBSD. This HOWTO outlines the necessary steps.

The procedure should work for the Windows Vista boot manager, too.

Setup

I am assuming a normal setup here, i.e.:

  • You have a working computer.
  • You want to install Windows 7 and FreeBSD on the same hard disk.
  • This hard disk is the primary disk.

FreeBSD installation

Perform a regular installation of FreeBSD. Create a partition, label the slices, choose the packages you want to install etc.

After the installation has finished, boot into your new system and copy /boot/boot1 to a safe location such as an USB stick.

Reboot and insert your Windows 7 DVD.

Windows 7 installation

Install Windows 7. You pretty much don't have any choices during the installation process except for selecting the correct partition. Double-check that you are not overwriting the FreeBSD partition.

After the installation has finished, boot into your new Windows system.

Configuring the Windows boot manager

Copy /boot/boot1 to C:\FreeBSD.mbr. We will now use some arcane magic that I have taken from OpenBSD's tome of answers and adapted for FreeBSD.

Open cmd.exe and create a new entry for the boot manager:

C:\Windows\system32> bcdedit /create /d "FreeBSD 7.2" /application bootsector
The entry {01234567-ABCD-ABCD-ABCD-0123456789AB} was successfully created.

C:\Windows\system32>

Substitute the GUID (i.e. {01234567-ABCD-ABCD-ABCD-0123456789AB}) that you received when executing the command from above for the next commands:

C:\Windows\system32> bcdedit /set {01234567-ABCD-ABCD-ABCD-0123456789AB} device boot
The operation completed successfully.

C:\Windows\system32> bcdedit /set {01234567-ABCD-ABCD-ABCD-0123456789AB} path \FreeBSD.mbr
The operation completed successfully.

C:\Windows\system32> bcdedit /set {01234567-ABCD-ABCD-ABCD-0123456789AB} device partition=c:
The operation completed successfully.

C:\Windows\system32> bcdedit /displayorder {01234567-ABCD-ABCD-ABCD-0123456789AB} /addlast
The operation completed successfully.

Further help is available if you call bcdedit /?. The documentation is also helpful if you want to fine-tune any settings.

Conclusion

This guide works perfectly for my system (FreeBSD 7.2 and Windows 7). There was not data loss or any other problem. However, I did a fresh install and restored from a backup. Your mileage may vary when you try to add Windows 7 to an existing installation of FreeBSD or vice versa.

In short: Be a man—take backups.

Posted Saturday afternoon, September 29th, 2018 Tags:

This is a small HOWTO about the BPF device under FreeBSD. I will show you how to access and configure this device. You will also learn how to send and receive ethernet frames. If you want to see an example for possible BPF uses, you might want to consider taking a look at in medias res.

Any C compiler should be able to compile the example code. Thanks to Pedro for pointing out several syntax errors.

What is the BPF?

The Berkeley Packet Filter is one of FreeBSD's most impressive devices. It provides you full ("raw") access to your NICs data link layers, i.e. you are totally protocol-independent. In general, you should be able to capture and send all packets that arrive on your network card, even if they are meant to reach other hosts (for example: if you are using a hub instead of a switch, higher-leveled raw interfaces will probably discard frames that are not for your MAC address. The BPF won't...). To use this really powerful device, you need a kernel that contains device bpf. If you don't know how to create your own kernel, take a look at the excellent FreeBSD handbook.

More information about the BPF is readily available via man 4 bpf.

Creating and configuring a BPF device

In order to create a functional, readable instance of the BPF device, you have to:

  • Open /dev/bpfn, where n depends on how many other applications are using a BPF
  • Associate your file descriptor with one network interface
  • Set the "immediate mode" so that a call to read will return immediately if a packet has been received
  • Request the BPF's buffer size

Let's proceed chronologically. First, we will try to open the next available BPF device:

char buf[ 11 ] = { 0 };
int bpf = 0;

for( int i = 0; i < 99; i++ )
{
    sprintf( buf, "/dev/bpf%i", i );
    bpf = open( buf, O_RDWR );

    if( bpf != -1 )
        break;
}

Now we are going to associate it with a specific network device, such as fxp0:

const char* interface = "fxp0";
struct ifreq bound_if;

strcpy(bound_if.ifr_name, interface);
if(ioctl( bpf, BIOCSETIF, &bound_if ) > 0)
    return(-1);

All's well at the moment, so let's enable immediate mode and request the buffer size. The last point is very important, as the BPF is allowed to provide you with more than one packet after issuing a call to read. If you know the buffer size, you can advance to the next packet.

int buf_len = 1;

// activate immediate mode (therefore, buf_len is initially set to "1")
if( ioctl( bpf, BIOCIMMEDIATE, &buf_len ) == -1 )
    return( -1 );

// request buffer length
if( ioctl( bpf, BIOCGBLEN, &buf_len ) == -1 )
      return( -1 );

Reading packets

Now, as we are completely done with the initialization and have a working file descriptor, we want to capture incoming traffic. The good thing about BPF is that you can set up filter rules if you only want to receive specific traffic, such as TCP/IP packets.

In theory, there is no need to do more than making a call to read. The resulting buffer contains a bpf_hdr and following after that, a packet. So one could just do something like that to convert this buffer into a valid ethernet frame:

frame = (ethernet_frame*) ( (char*) bpf_buf + bpf_buf->bh_hdrlen);

Unfortunately, sometimes the kernel likes to add more than one packet to your buffer. Well, the lazy approach would just read one packet per buffer, and wait for the TCP retransmissions that may arrive. But being lazy is not a good solution. Therefore, we need a loop to read all packets that are in the buffer:

int read_byes = 0;

ethernet_frame* frame;
struct bpf_hdr* bpf_buf = new bpf_hdr[buf_len];
struct bpf_hdr* bpf_packet;

while(run_loop)
{
    memset(bpf_buf, 0, buf_len);

    if((read_bytes = read(bpf, bpf_buf, buf_len)) > 0)
    {
        int i = 0;

        // read all packets that are included in bpf_buf. BPF_WORDALIGN is used
        // to proceed to the next BPF packet that is available in the buffer.

        char* ptr = reinterpret_cast<char*>(bpf_buf);
        while(ptr < (reinterpret_cast<char*>(bpf_buf) + read_bytes))
        {
            bpf_packet = reinterpret_cast<bpf_hdr*>(ptr);
            frame = (ethernet_frame*)((char*) bpf_packet + bpf_packet->bh_hdrlen);

            // do something with the Ethernet frame
            // [...]

            ptr += BPF_WORDALIGN(bpf_packet->bh_hdrlen + bpf_packet->bh_caplen);
        }
    }
}

The above loop does the following things:

  • As long as the "distance" between the original bpf_buf and the auxiliary pointer ptr is not bigger as the number of bytes actually read...

  • ...the auxiliary pointer is advanced to the next ethernet frame. BPF_WORDALIGN rounds up to the next even multiple of BPF_ALIGNMENT. This means that you will jump over all bytes that are used for padding purposes. Hence, bpf_packet always points to the next bpf_hdr structure, always given the fact that there is more than one.

Please note that ethernet_frame is my own structure used to describe one ethernet frame (802.3). Read the standard RFCs or use Wireshark if you want to learn more.

Sending (your own) packets

Sometimes, you might want to send your own packets instead of sticking to the analysis of captured ones. No problem with the BPF. If the BPF is initialised as aforementioned, sending packets is really no problem at all. A quick call to write will do the trick:

write(bpf, frame, bpf_buf->bh_caplen);

In this snippet, bpf is the BPF's file descriptor, frame is a pointer to an ethernet frame that has a TCP/IP packet attached (remember the initialization of frame above?). Of course, this is totally useless, but if you want to write a little broadcast router or something like that, you could just change the destination MAC address and write the more or less unchanged frame plus the payload to the BPF. You won't have to care about the source MAC address, as the BPF does that for you (look at the man page and search for BIOCGHDRCMPLT if you want to disable this feature).

Ethernet frames

An ethernet frame is the basic structure that is sent through your network cables. You have to use it if you need to access the link layer, i.e. if you want to send your own raw packets. This is how an ethernet frame (802.3, ethernet version 2.0) could look like:

destination hardware (MAC) address [6 bytes] source hardware (MAC) address [6 bytes] layer-3 protocol type [2 bytes] payload [46 - 1500 bytes] FCS [4 bytes]

The FCS field is not necessarily needed. The other attributes should be initialised, except the source MAC address (see above for explanation). This is what you should do if you want to send your own packets:

  • Prepare one ethernet frame and supply it with the proper values
  • Pay particular attention to the type field. Otherwise, you might experience errors (for example: IP packets with an ARP type field).
  • Attach the payload. For an arbitrary TCP/IP packet, you would need:
    • IP header
    • TCP header
    • TCP payload
  • Send it!
  • For debugging purposes, you should have a network sniffer which will tell you if something went wrong.

Following the given example, your frame could look like this:

01:02:03:04:05:06 Destination MAC
01:02:03:04:05:06 Source MAC
0x0800 Type: IP
IP header
TCP header
TCP payload

Conclusion

The BPF clearly is a very powerful thing. If you know something about the underlying network structure, you can do unbelievable things with it. Of course, you do not need to stick to the TCP. For a nice example of using the BPF, take a look at IMR, a man-in-the-middle application that uses ARP and directs traffic between two victim hosts.

Additional information is available through these documents:

You could also take a closer look on the additional BPF flags, for example BIOCGHDRCMPLT. This flag allows you to fill in the link level source address of an ethernet frame by yourself, thus allowing you to create arbitrary spoofed packets that may trick other hosts in your network.

Posted Saturday afternoon, September 29th, 2018 Tags:

I recently wanted to download some contact data from the address book of my Nokia 6300 mobile. It turned out that this is less painful than it sounds: By using the gnokii package, I was able to get a dump of my address book in VCARD format.

Installation and configuration

  • gnokii is available in the ports collection. Great.
  • Copy /usr/local/etc/gnokiirc.sample to .gnokiirc
  • Modify .gnokiirc

Since the defaults of this file are good, I only had to change the following lines:

# Since I want a USB connection
port = 1
connection = dku2libusb

# Other phones may require other settings, of course
model = series40

Connecting the phone

  • Using a USB-to-mini-USB cable, connect the phone
  • When the phone asks about the connection mode, select Ǹokia mode (or something similar)
  • Issue a gnokii --identify command to check whether the phone is reachable

Dumping the address book

This required some reading. The manpage of gnokii is written rather well, fortunately. In the end I resorted to:

gnokii --getphonebook ME 1 end -v > contacts.vcf

This takes all contacts (hence the 1 end) from the internal memory of the phone, converts them to the VCARD format, and stores them in contacts.vcf, where they may be updated and processed.

Posted Saturday afternoon, September 29th, 2018 Tags:

K3b is a great CD/DVD authoring software. This small tutorial explains how to use it with non-root user accounts. This HOWTO is also applicable if you want to get k9copy working. You can skip setting SUID flags in this case.

Kernel setup

First, let's check whether you have to do anything about your kernel setup at all. Execute camcontrol devlist in a terminal. If you see your CD/DVD writer, all is well. For example, this is the output of the command when being run on my good old Thinkpad R50e:

/home/bastian % camcontrol devlist
<MATSHITA DVD-RAM UJ-830Sx 1.00>   at scbus1 target 0 lun 0 (pass0,cd0)

If you don't see your hardware, let's try something else: This is as easy as it gets: Either add atapicam_load="YES" in /boot/loader.conf or compile a new kernel that contains device atapicam.

This should do the trick.

DevFs configuration

You need to set the proper permissions for the CD/DVD drive. If you look at the output from camcontrol devlist from above, you will notice the part (pass0,cd0). If you have multiple CD/DVD drives in your computer, the numbers will be different. Substitute the correct numbers for your system in the lines below.

Open /etc/devfs.conf and add the following lines at a convenient location:

# Allow CD/DVD authoring
perm cd0   0660
perm pass0 0660
perm xpt0  0660

If you are the only user of your computer, simply add your account to the operator group (which owns the devices by default).

If you want to enable burning for multiple users, however, I would strongly suggest creating an appropriate user group (e.g. burn) and adding the user accounts that are allowed to burn CDs/DVDs. In this case, in addition to the lines from above, the following lines should also be added to /etc/devfs.conf:

own cd0   root:burn
own pass0 root:burn
own xpt0  root:burn

Set SUID flags

Skip this step if you are trying to install k9copy.

I don't like it very much, but is necessary to endow cdrdao and cdrecord with root permissions. So, su to root and execute:

chmod u+s /usr/local/bin/cdrdao
chmod u+s /usr/local/bin/cdrecord

Enable DMA

Execute sysctl hw.ata.atapi_dma to check whether DMA is enabled for CD/DVD drives:

/home/bastian % sysctl hw.ata.atapi_dma
hw.ata.atapi_dma: 1

If the output is 0, add hw.ata.atapi_dma=1 to /etc/sysctl.conf.

Conclusion

K3b or k9copy should work now. If you want to enable user mounting of CDs/DVDs, add vfs.usermount=1 to /etc/sysctl.conf.

Posted Saturday afternoon, September 29th, 2018 Tags:

This short note explains how to use the font "Adobe Minion Pro" with the LaTeX typesetting system.

Luckily, all the work has already been done by other people. Plus, the font is available for free by downloading Adobe Reader.

Preparation

  • Download an older version of Adobe Acrobat Reader. Choose the .tar.gz for Linux. It is vital that you do not download the most recent version. Unfortunately, the font metrics (which we will install later) do not work with the most recent version of the font.
  • Extract the archive; the font is in the file COMMON.TAR in the directory Adobe/Reader8/Resource/Font.
  • Install otfinfo from /usr/ports/print/typetools (for FreeBSD users) or using the package manager of your choice.
  • Use otfinfo -v to inspect the fonts. For MinionPro-Bold.otf, I get Version 2.015;PS 002.000;Core 1.0.38;makeotf.lib1.7.9032. This version works for me.
  • If not already done, create a local texmf-structure. For the venerable teTeX-distribution, I had to set the environment variable TEXMFHOME to $HOME/.texmf. I also created the directories .texmf, .texmf-config, .texmf-var.
  • Copy updmap.cfg to $HOME/.texmf-config/web2c/. This file needs to be modified for the new font.
  • Run texhash

Font installation

Follow the excellent documentation from CTAN. You will be provided with detailed step-by-step instructions and some helpful scripts that convert the fonts. After placing everything in the correct directory (as the tutorial suggest), you are good to go: A simple \usepackage{MinionPro} should do the trick.

My gratitude goes to Achim Blumensath, Andreas Bühmann, and Michael Zedler for creating and maintaining the aforementioned package. Otherwise, I would have been hopelessly lost in the mazes of my own incompetence.

Posted Saturday afternoon, September 29th, 2018 Tags:

This HOWTO describes the installation of FreeBSD 6.2 on a Thinkpad R50e. For your convenience, I also included parts of the configuration files you might consider useful. All in all, the R50e is a perfect notebook for FreeBSD. Every important device is usable, allowing you to be productive without major annoyances.

Installation

There is a small partition containing something like a rescue system from IBM. To make things simpler, you might decide to keep it. But removing it and using the whole hard disk for your installation should not hurt, either (this is my personal experience).

The actual installation process is really straightforward. Install FreeBSD any way you want.

WLAN

The WLAN chipset driver is now included in the kernel. Simply add the following line to /boot/loader.conf in order to enable it:

if_iwi_load="YES"

Caveat: The driver version I used had some problems when connecting to hidden access points. I recommend turning the SSID broadcast on. Since you, being security-minded, are using WPA2 anyway, this won't decrease your security.

ACPI and powerd configuration

Assuming you want to use ACPI/powerd, there are several things that have to be configured first. Automatic CPU frequency adjustment has to be set up via /etc/rc.conf:

powerd_enable="YES"
powerd_flags="-b adaptive -a max"
performance_cx_lowest="C2"
performance_cpu_freq="1399"
economy_cx_lowest="C3"
economy_cpu_freq="NONE"

These settings seem reasonable to me. However, you might want to change them if you have other objectives. I was told that SpeedStep should be disabled on a R50e, so add hint.ichss.0.disabled="1" to /boot/loader.conf.

The ACPI configuration is quite fast, too. These lines belong into /etc/sysctl.conf:

kern.timecounter.hardware=i8254
debug.acpi.do_powerstate=1

hw.acpi.lid_switch_state=S3
hw.acpi.standby_state=S1
hw.acpi.suspend_state=S3
hw.acpi.sleep_button_state=S3
hw.acpi.sleep_delay=3
hw.acpi.reset_video=0

This allows your Thinkpad to suspend when you close the lid. To enable the Thinkpad keys that control suspension, add acpi_ibm_load="YES" to your /boot/loader.conf. You might also want to take a look at deskutils/tpb. This program is a port that allows you to redefine the (mostly unused) Thinkpad keys.

Sound

snd_ich_load="YES" in /boot/loader.conf enables the sound card.

Posted at teatime on Saturday, September 29th, 2018 Tags: