Wednesday, March 10, 2010
Pocket Linux Guide
The Linux Documentation Project
This document takes baby steps to explains how to build a small diskette-based GNU/Linux system. This is a very good starting place for Linux newbies to understand how basic linux system works.
Labels:
Kernel
,
linux
,
Pocket Linux
,
Ramdisk
Get information about all the network interfaces in linux
This program lists all active network interfaces in the system with associated IP address, MAC address and the subnetmask.
#include <stdio.h> #include <string.h> #include <errno.h> #include <unistd.h> #define __KERNEL__ #include <asm/types.h> #undef __KERNEL__ #include <linux/ethtool.h> #include <linux/sockios.h> #include <net/if.h> #include <sys/ioctl.h> #include <arpa/inet.h> /* this is straight from beej's network tutorial. It is a nice wrapper * for inet_ntop and helpes to make the program IPv6 ready */ char *get_ip_str(const struct sockaddr *sa, char *s, size_t maxlen) { switch(sa->sa_family) { case AF_INET: inet_ntop(AF_INET, &(((struct sockaddr_in *)sa)->sin_addr), s, maxlen); break; case AF_INET6: inet_ntop(AF_INET6, &(((struct sockaddr_in6 *)sa)->sin6_addr), s, maxlen); break; default: strncpy(s, "Unknown AF", maxlen); return NULL; } return s; } int main (int argc, char **argv) { char buf[1024] = {0}; struct ifconf ifc = {0}; struct ifreq *ifr = NULL; int sck = 0; int nInterfaces = 0; int i = 0; struct ifreq ifr_subnet; struct sockaddr *addr_subnet = NULL; /* Get a socket handle. */ sck = socket(AF_INET, SOCK_DGRAM, 0); if(-1 == sck) { perror("socket"); return 1; } /* Query available interfaces. */ ifc.ifc_len = sizeof(buf); ifc.ifc_buf = buf; if(-1 == ioctl(sck, SIOCGIFCONF, &ifc)) { perror("ioctl(SIOCGIFCONF)"); close (sck); return 1; } /* Iterate through the list of interfaces. */ ifr = ifc.ifc_req; nInterfaces = ifc.ifc_len / sizeof(struct ifreq); for(i = 0; i < nInterfaces; i++) { struct ifreq *item = &ifr[i]; /* Show the device name and IP address */ struct sockaddr *addr = &(item->ifr_addr); char ip[INET6_ADDRSTRLEN]; printf("%s: IP %s", item->ifr_name, get_ip_str(addr, ip, INET6_ADDRSTRLEN)); /* Get the MAC address */ if(-1 == ioctl(sck, SIOCGIFHWADDR, item)) { perror("ioctl(SIOCGIFHWADDR)"); close (sck); return 1; } /* display result */ printf(", MAC %.2x:%.2x:%.2x:%.2x:%.2x:%.2x ", (unsigned char)item->ifr_hwaddr.sa_data[0], (unsigned char)item->ifr_hwaddr.sa_data[1], (unsigned char)item->ifr_hwaddr.sa_data[2], (unsigned char)item->ifr_hwaddr.sa_data[3], (unsigned char)item->ifr_hwaddr.sa_data[4], (unsigned char)item->ifr_hwaddr.sa_data[5]); /* Reset the memory allocated for ifreq */ memset (&ifr_subnet, 0, sizeof (struct ifreq)); /* Update interface name into ifreq */ strcpy (ifr_subnet.ifr_name, item->ifr_name); /* Call ioctl function */ if(-1 == ioctl (sck, SIOCGIFNETMASK, &ifr_subnet )) { perror("ioctl(SIOCGIFNETMASK)"); close (sck); return 1; } addr_subnet = &(ifr_subnet.ifr_addr); printf("SubnetMask: %s\n", get_ip_str(addr_subnet, ip, INET6_ADDRSTRLEN)); } close (sck); return 0; }
Reference: http://www.adamrisi.com/?p=84
Labels:
C
,
interface
,
ioctl
,
ipaddress
,
IPV4
,
IPV6
,
linux
,
mac address
,
network interfaces
,
Networking
,
Programming
,
Socket
,
subnetmask
Tuesday, March 9, 2010
Simple PING implementation in C
#include <netinet/in.h> #include <netinet/ip.h> #include <netinet/ip_icmp.h> #include <arpa/inet.h> #include <netdb.h> #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <sys/signal.h> #include <string.h> #define DEFDATALEN 56 #define MAXIPLEN 60 #define MAXICMPLEN 76 static char *hostname = NULL; static int in_cksum(unsigned short *buf, int sz) { int nleft = sz; int sum = 0; unsigned short *w = buf; unsigned short ans = 0; while (nleft > 1) { sum += *w++; nleft -= 2; } if (nleft == 1) { *(unsigned char *) (&ans) = *(unsigned char *) w; sum += ans; } sum = (sum >> 16) + (sum & 0xFFFF); sum += (sum >> 16); ans = ˜sum; return (ans); } static void noresp(int ign) { printf("No response from %s\n", hostname); exit(0); } static void ping(const char *host) { struct hostent *h; struct sockaddr_in pingaddr; struct icmp *pkt; int pingsock, c; char packet[DEFDATALEN + MAXIPLEN + MAXICMPLEN]; if ((pingsock = socket(AF_INET, SOCK_RAW, 1)) < 0) { /* 1 == ICMP */ perror("ping: creating a raw socket"); exit(1); } /* drop root privs if running setuid */ setuid(getuid()); memset(&pingaddr, 0, sizeof(struct sockaddr_in)); pingaddr.sin_family = AF_INET; if (!(h = gethostbyname(host))) { fprintf(stderr, "ping: unknown host %s\n", host); exit(1); } memcpy(&pingaddr.sin_addr, h->h_addr, sizeof(pingaddr.sin_addr)); hostname = h->h_name; pkt = (struct icmp *) packet; memset(pkt, 0, sizeof(packet)); pkt->icmp_type = ICMP_ECHO; pkt->icmp_cksum = in_cksum((unsigned short *) pkt, sizeof(packet)); c = sendto(pingsock, packet, sizeof(packet), 0, (struct sockaddr *) &pingaddr, sizeof(struct sockaddr_in)); if (c < 0 || c != sizeof(packet)) { if (c < 0) perror("ping: sendto"); fprintf(stderr, "ping: write incomplete\n"); exit(1); } signal(SIGALRM, noresp); alarm(2); /* give the host 5000ms to respond */ /* listen for replies */ while (1) { struct sockaddr_in from; size_t fromlen = sizeof(from); if ((c = recvfrom(pingsock, packet, sizeof(packet), 0, (struct sockaddr *) &from, &fromlen)) < 0) { if (errno == EINTR) continue; perror("ping: recvfrom"); continue; } if (c >= 76) { /* ip + icmp */ struct iphdr *iphdr = (struct iphdr *) packet; pkt = (struct icmp *) (packet + (iphdr->ihl << 2)); /* skip ip hdr */ if (pkt->icmp_type == ICMP_ECHOREPLY) break; } } printf("%s is alive!\n", hostname); return; } int main () { ping ("192.168.1.2"); }
Reference: http://www.koders.com/c/fid30EA22902AFF5800481BBC6F65DADCDAF92D6E37.aspx
Labels:
C
,
Echo
,
ICMP
,
linux
,
Networking
,
Ping
,
Programming
,
Socket
Monday, March 8, 2010
Add new option in configure script in autobuild system
Example:
To get a new option "--with-unit-test" when you run "./configure --help"
add the following block in "configure.ac"
and you Makefile.am will look like this,
and take care of UNIT_TEST macro check in the source code.
To get a new option "--with-unit-test" when you run "./configure --help"
Optional Packages: --with-unit-test Create binary to unit test the library package (default is no)
add the following block in "configure.ac"
AC_MSG_CHECKING([--with-unit-test]) AC_ARG_WITH(unit-test, AC_HELP_STRING([--with-unit-test], [Create binary to unit test the library package (default is no)]), [unittest="yes"], [unittest="no"] ) AM_CONDITIONAL(UNIT_TEST, test "$unittest" = "yes") AC_MSG_RESULT([$unittest])
and you Makefile.am will look like this,
bindir = $(prefix)/usr/local/bin libdir = $(prefix)/usr/local/lib if UNIT_TEST bin_PROGRAMS = unittest unittest_SOURCES = source1.c \ Source2.c unittest_CFLAGS = -I@top_srcdir@/include \ -DUNIT_TEST unittest_LDFLAGS = else lib_LTLIBRARIES = libunittest.la libunittest_la_SOURCES = source2.c \ source3.c libunittest_la_CFLAGS = -I@top_srcdir@/include libunittest_la_LDFLAGS = -version-info 0:1:0 endif
and take care of UNIT_TEST macro check in the source code.
Labels:
autobuild
,
autoconf
,
automake
,
Compilation
,
configure
,
configure.ac
,
make
,
Makefile
,
Makefile.am
How to create self-Extracting script
It involves 3 steps,
This is a tar ball in which all the installable binaries, libraries, script files, configuration files, etc will be placed in the same file hierarchy of the target board considering the base directory of the tar ball is the installation directory on the target board.
Note: There should not be any space after "__ARCHIVE__" and should be a new line after "__ARCHIVE__".
Installer for your package "Package-Version.sh" is ready.
Source: Linux Journal
- Create Payload
- Create Installer script
- Packaging
This is a tar ball in which all the installable binaries, libraries, script files, configuration files, etc will be placed in the same file hierarchy of the target board considering the base directory of the tar ball is the installation directory on the target board.
periask@ubuntu:~$ mkdir -vp packaging/Payload mkdir: created directory `packaging mkdir: created directory `packaging/Payload' periask@ubuntu:~$ cd packaging/Payload periask@ubuntu:~/packaging/Payload$ cp --preserve=mode -rl <installables> . periask@ubuntu:~/packaging/Payload$ tar zcf ../Payload.tar.gz . periask@ubuntu:~/packaging/Payload$ cd .. periask@ubuntu:~/packaging$
Create Installer Script:
Copy the below content and create "installer" file in "packaging" directory.
#!/bin/bash # Get the starting point of the tar ball SKIP=`awk '/^__ARCHIVE__/ { print NR + 1; exit 0; }' $0` # Do pre-installation steps here. # Extracting the tar ball Which is appended to this file tail -n "+$SKIP" $0 >/dev/null 2>&1 if [ $? -eq 0 ]; then tail -n +$SKIP $0 | gunzip -c | tar -C / -xvf - else tail +$SKIP $0 | gunzip -c | tar -C / -xvf - fi # Do post-installation steps here. exit 0 __ARCHIVE__
Note: There should not be any space after "__ARCHIVE__" and should be a new line after "__ARCHIVE__".
Packaging:
Concatenate the file "installer" and "Payload.tar.gz" and create the package file.
periask@ubuntu:~/packaging$ cat installer Payload.tar.gz > Package-Version.sh periask@ubuntu:~/packaging$ chmod +x Package-Version.sh
Installer for your package "Package-Version.sh" is ready.
Source: Linux Journal
Labels:
awk
,
Bash
,
Installer
,
Package management
,
Packaging
,
Self-Extracting script
,
Shell scripting
Avahi-autoipd
It is an Zeroconf implementation of Avahi which facilitates configuration of a network element automatically on the local network in the absence of DHCP server. It uses a special address range 169.254.0.0/16 and prefix fe80::/16 for IPV4 and IPV6 link-local addressing respectively. When the autoipd daemon starts, it generates an IP address randomly using the MAC address information and announces its new IP using ARP probe to find address conflict. If the given address is being used by another network element, it generates a new IP and does ARP probe till it successfully claims the address. It stores this IP address in a file for persistence across network restart (file location on linux machine will be "/var/lib/avahi-autoipd/<mac_address>"). To configure this address to be routable on the local link, autoipd adds routing rule for this IP address in the routing table.
Source: RFC3927, Avahi
Source: RFC3927, Avahi
Labels:
Autoipd
,
Avahi
,
Link-local address
,
Networking
,
Service discovery
,
Zeroconf
Subscribe to:
Posts
(
Atom
)