This may be old news but I just discovered some handy auto-generated (with doxygen) kernel documentation:
Auto-generated Linux Kernel Documentation
January 25, 2012Enabling dev_dbg in the kernel
November 6, 2011To enable dev_dbg messages in a specific kernel file:
#define DEBUG
before including <linux/device.h>
Reference: https://lkml.org/lkml/2007/6/29/323
Retrieve information about the calling process from within a kernel module
October 18, 2011From within a kernel module you can get information about the currently executing process using the current variable. current is of type struct task_struct. When a system call is executing (such as open, read, write, ioctl) the current process will be the caller.
For example to display the process id from within a read function:
printk("%s: The calling process is \"%s\" (pid %i)\n",
__FUNCTION__, current->comm, current->pid);
References:
J. Corbet, A. Rubini, & G. Kroah-Hartman. (2005). Linux Device Drivers, 3rd Ed. (p. 20)
Sending raw Ethernet packets from a specific interface in C on Linux
September 14, 2011Lately I’ve been writing some code to send packets to a specific MAC address from a specific interface. I’m sure this will come in handy again so here is how it goes:
Includes:
(might not need all of these)
#include <netinet/in.h> #include <sys/socket.h> #include <arpa/inet.h> #include <net/if.h> #include <netinet/ip.h> #include <netinet/udp.h> #include <netinet/ether.h> #include <linux/if_packet.h>
Open the raw socket:
int sockfd;
...
/* Open RAW socket to send on */
if ((sockfd = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW)) == -1) {
perror("socket");
}
Get the index of the interface to send on:
struct ifreq if_idx;
...
memset(&if_idx, 0, sizeof(struct ifreq));
strncpy(if_idx.ifr_name, "eth0", IFNAMSIZ-1);
if (ioctl(sock, SIOCGIFINDEX, &if_idx) < 0)
perror("SIOCGIFINDEX");
Get the MAC address of the interface to send on:
struct ifreq if_mac;
...
memset(&if_mac, 0, sizeof(struct ifreq));
strncpy(if_mac.ifr_name, "eth0", IFNAMSIZ-1);
if (ioctl(sock, SIOCGIFHWADDR, &if_mac) < 0)
perror("SIOCGIFHWADDR");
Get the IP address of the interface to send on:
struct ifreq if_ip;
...
memset(&if_ip, 0, sizeof(struct ifreq));
strncpy(if_ip.ifr_name, "eth0", IFNAMSIZ-1);
if (ioctl(sock, SIOCGIFADDR, &if_ip) < 0)
perror("SIOCGIFADDR");
Construct the Ethernet header:
int tx_len = 0; char sendbuf[1024]; struct ether_header *eh = (struct ether_header *) sendbuf; ... memset(sendbuf, 0, 1024); /* Ethernet header */ eh->ether_shost[0] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[0]; eh->ether_shost[1] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[1]; eh->ether_shost[2] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[2]; eh->ether_shost[3] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[3]; eh->ether_shost[4] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[4]; eh->ether_shost[5] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[5]; eh->ether_dhost[0] = MY_DEST_MAC0; eh->ether_dhost[1] = MY_DEST_MAC1; eh->ether_dhost[2] = MY_DEST_MAC2; eh->ether_dhost[3] = MY_DEST_MAC3; eh->ether_dhost[4] = MY_DEST_MAC4; eh->ether_dhost[5] = MY_DEST_MAC5; eh->ether_type = htons(ETH_P_IP); tx_len += sizeof(struct ether_header);
Construct the IP header:
struct iphdr *iph = (struct iphdr *) (sendbuf + sizeof(struct ether_header));
...
/* IP Header */
iph->ihl = 5;
iph->version = 4;
iph->tos = 16; // Low delay
iph->id = htons(54321);
iph->ttl = ttl; // hops
iph->protocol = 17; // UDP
/* Source IP address, can be spoofed */
iph->saddr = inet_addr(inet_ntoa(((struct sockaddr_in *)&if_ip.ifr_addr)->sin_addr));
// iph->saddr = inet_addr("192.168.0.112");
/* Destination IP address */
iph->daddr = inet_addr("192.168.0.111");
tx_len += sizeof(struct iphdr);
Construct the UDP header:
struct udphdr *udph = (struct udphdr *) (sendbuf + sizeof(struct iphdr) + sizeof(struct ether_header)); ... /* UDP Header */ udph->source = htons(3423); udph->dest = htons(5342); udph->check = 0; // skip tx_len += sizeof(struct udphdr);
Fill in UDP payload:
/* Packet data */ sendbuf[tx_len++] = 0xde; sendbuf[tx_len++] = 0xad; sendbuf[tx_len++] = 0xbe; sendbuf[tx_len++] = 0xef;
Fill in remaining header info:
unsigned short csum(unsigned short *buf, int nwords)
{
unsigned long sum;
for(sum=0; nwords>0; nwords--)
sum += *buf++;
sum = (sum >> 16) + (sum &0xffff);
sum += (sum >> 16);
return (unsigned short)(~sum);
}
...
/* Length of UDP payload and header */
udph->len = htons(tx_len - sizeof(struct ether_header) - sizeof(struct iphdr));
/* Length of IP payload and header */
iph->tot_len = htons(tx_len - sizeof(struct ether_header));
/* Calculate IP checksum on completed header */
iph->check = csum((unsigned short *)(sendbuf+sizeof(struct ether_header)), sizeof(struct iphdr)/2);
Send the raw Ethernet packet:
/* Destination address */
struct sockaddr_ll socket_address;
...
/* Index of the network device */
socket_address.sll_ifindex = if_idx.ifr_ifindex;
/* Address length*/
socket_address.sll_halen = ETH_ALEN;
/* Destination MAC */
socket_address.sll_addr[0] = MY_DEST_MAC0;
socket_address.sll_addr[1] = MY_DEST_MAC1;
socket_address.sll_addr[2] = MY_DEST_MAC2;
socket_address.sll_addr[3] = MY_DEST_MAC3;
socket_address.sll_addr[4] = MY_DEST_MAC4;
socket_address.sll_addr[5] = MY_DEST_MAC5;
/* Send packet */
if (sendto(sock, sendbuf, tx_len, 0, (struct sockaddr*)&socket_address, sizeof(struct sockaddr_ll)) < 0)
printf("Send failed\n");
References:
http://aschauf.landshut.org/fh/linux/udp_vs_raw/ch01s03.html
http://www.tenouk.com/Module43a.html
http://linux.die.net/man/3/sendto
Initialising all elements of an array to a constant in C
August 16, 2011Works in GCC 4.4.3:
int myArr[] = {[0 ... (MAX_NO_ELEMENTS-1)] = 3};
Reference: http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Designated-Inits.html
How to make your Tumblr display in chronological order
August 11, 2011- Add a tag to every post (just something like ‘x’)
- Use the address 987fsdf98uj23r.tumblr.com/tagged/x/chrono
Reference: http://staff.tumblr.com/post/34933619/new-feature-tag-filtering
Copying files between Linux VirtualBox guest and host
August 8, 2011In VirtualBox go to “Network Adapters…” from the Devices menu and set Attached to: Host-only Adapter.

Set up IP addresses in the same sub domain. On the host:
ifconfig vboxnet0 192.168.56.1 netmask 255.255.255.0
On the guest:
ifconfig eth0 192.168.56.2 netmask 255.255.255.0
route add default gw 192.168.56.1
Use secure copy to transfer files from host to guest. From the host:
scp filetocpy guestuser@192.168.56.2:/guestdir/
Lessons learned submitting my first Linux kernel patch
July 31, 2011- It takes a lot longer than one would expect
- Follow all the instructions
- Create patch with -upNr options:
diff -upNr a/drivers/somefile.c b/drivers/somefile.c > mypatch.patch - Use the script to check for coding style errors:
cd a
scripts/checkpatch.pl ../mypatch.patch - When using Evolution to mail patches, turn off word wrapping by changing to Preformatted paragraph style:

- More reading
Digitech Gigabit Ethernet ExpressCard on Ubuntu 10.04
June 8, 2011Trick my colleague showed me to get the Digitech XC4146 PCMCIA-E-GLAN Gigabit Ethernet ExpressCard working on Ubuntu 10.04:
echo 1 | sudo tee /sys/bus/pci/rescanVintage Game Console RF Frequencies
June 4, 2011My LCD TV has a lot of trouble scanning for old game consoles. Here are mine as I tune them in:
| Console | Channel switch | Frequency (MHz) |
| NES | to the left | 46.35 |