A ping utility is used to check the availability of a remote host. I wanted to implement the function in my project. But it is not so easy as I had expected. Since administrator/root privilege is required to create a raw socket under windows/linux, and this is not what I want.

Finally, I chose to utilize system’s ping via CreateProcess()/execve() function. Under windows, ping may used IcmpSendEcho() API to wrap the creation of a raw socket, and this does not require administrator privilege. But it is still not working when logged in as a guest. Under linux, ping is a +s(setuid) utility, which means it is always run with root privilege. Anyway, I still tried to implement ping by using raw socket and sending raw ICMP(Internet Control Message Protocol) messages.

A raw ICMP echo request message has a ICMP header, while a raw ICMP echo reply message has an additional IP header in front of the ICMP header. Say:

There are several ICMP message types defined in RFC 792, but we only care about the echo type. So here’s our definition of a IP header and a ICMP header:

Our customized ICMP echo request/reply definition with self-defined data field:

The raw socket is created with:

Sending a ICMP echo request:

We simply use the checksum algorithm found in the original ping program from Mike Muuss.

Now, receiving a ICMP echo reply:

You may have noticed the if/else clause in the receive function. The use_icmp_socket flag is used to tell which socket type is used when sending a ICMP message. In linux kernel 3.0, a new socket type is introduced to reduce the possibility to use a raw socket that only send ICMP echo messages. Thus, the classic ping utility can be no longer a +s(setuid) one. A ICMP socket can be created with:

Note the difference in the second parameter. A kernel parameter(/proc/sys/net/ipv4/ping_group_range) in comment above should be set to indicate which UID range is allowed to use a ICMP socket.

When using a raw socket, the TTL value is in the IP header. While, the TTL value is in the socket ancillary data when using a ICMP socket, the reply data does not contain IP header any more. And we must set a socket option explicitly to retrieve the TTL value:

Let’s put them all together:

All code compiles and works under Ubuntu 12.04(gcc4.6), Windows XP(VS2005) and Windows 7(VS2010) with administrator/root privilege. After enabling the ICMP socket parameter, root privilege is not required under linux. The output may look like:

Reference:
– RFC 791: http://tools.ietf.org/html/rfc791
– RFC 792: http://tools.ietf.org/html/rfc792
– Implement ping in C: http://www.ibm.com/developerworks/cn/linux/network/ping/
– Raw Socket and ICMP: http://courses.cs.vt.edu/cs4254/fall04/slides/raw_6.pdf
– Linux Kernel 3.0: http://kernelnewbies.org/Linux_3.0
– IPv4: Add ICMP Socket Kind: http://lwn.net/Articles/420800/
– Patch for Userspace ping: ftp://ftp.intelib.org/pub/segoon/iputils-ss020927-pingsock.diff
– Wine Implementation: http://fossies.org/dox/wine-1.4.1/icmp_8c_source.html

Generally, A logger is a singleton class. The declaration may look like:

The Init function is used to set log name or maybe other configuration information. And We can use the Write function to write logs.

Well, in a multithreaded environment, locks must be added to prevent concurrent issues and keep the output log in order. And sometimes we want to have separate log configurations. How can we implement it without breaking the original interfaces?

One easy way is to maintain a list of all available Logger instances, so that we can find and use a unique Logger in each thread. The approach is somehow like the one used in log4j. But log4j reads configuration files to initialize loggers, while our configuration information is set in runtime.

Another big issue is that we must add a new parameter to the GetInstance function to tell our class which Logger to return. The change breaks interfaces.

By utilizing TLS (thread-local storage), we can easily solve the above issues. Every logger will be thread-local, say every thread has its own logger instance which is stored in its thread context. Here comes the declaration for our new Logger class, boost::thread_specific_ptr from boost library is used to simplify our TLS operations:

Simply use boost::thread_specific_ptr to wrap the original 2 static variables, and they will be in TLS automatically, that’s all. The implementation:

Our test code:

Output when using the original Logger may look like:

When using the TLS version, it may look like:

Everything is in order now. You may want to know what OS API boost uses to achieve TLS. I’ll show you the details in boost 1.43:

The underlying API is TlsGetValue under windows and pthread_getspecific under *nix platforms.

Just downloaded and tried Visual Studio 2012(with update 2, version 11.0.60315.01). The Windows XP targeting is available(actually already available in update 1):

 photo vs2012_xp_target_zps10d34c42.png

The executable generated by the original VS2012 toolchain does not run under Windows XP. A error message box is shown:

 photo vs2012_xp_target_2_zpsc799786a.png

In update 1, the static and dynamic link libraries for the CRT, STL and MFC have been updated in-place to add runtime support for Windows XP and Windows Server 2003. And the runtime version is upgraded to 11.0.51106.1 from 11.0.50727.1.

Except the library update, there’s none real difference when selecting “v110” or “v110_xp” toolchain. I wrote a simple HelloWorld application and compare the two generated binary.

And the output:

The first difference represents the timestamps of the two binary. The other two differences standard for “Operating System Version” and “Subsystem Version”. We have 5.1 for Windows XP, 6.0 for Windows Vista and later. That’s all. And we can easily build a Windows XP binary from the command line with only one additional linker switch:

I also built a simple MFC application(dynamic link to MFC) with Windows XP target in VS2012. It runs fine under Windows XP with MFC DLLs copied in the same directory. From VS2010, the SxS assembly is not used any more. All you need to do is copy the dependent DLLs to the application directory and run.

Reference: http://blogs.msdn.com/b/vcblog/archive/2012/10/08/10357555.aspx

First, here’s the original indexer preference page of eclipse 3.5 (CDT 6.0):

eclipse35_cdt60

In eclipse 3.6 (CDT 7.0), the full indexer is removed in favour of the fast indexer.

eclipse36_cdt70

And in eclipse 3.7 (CDT 8.0), there seems to be no big changes, “Index source and header files opened in editor) is added and set to false by default:

eclipse37_cdt80

Now, here’s the indexer preference page of eclipse 3.8/4.2 (CDT 8.1). Two changes: 1) Bug 197989 – Headers included in different variants are not supported. 2) Bug 377992 – Enable the “Index unused headers” preference by default. In addition, option to parse files up-front from UI is removed.

eclipse38_cdt81

I just want to read source code of apr and glib, to learn from them. When I created a C project and imported all files into it, some symbols were unresolved or wrongly resolved. In eclipse 3.7/3.8 (CDT 8.0/8.1), I managed to work it out by importing only unix-specific source files.

There’s a performance issue in eclipse Juno 4.2, but Juno 3.8 is not affected. So I strongly suggest to use 3.8 version. Since there’s no all-in-one package for 3.8. It is suggested to download the platform package (not the huge SDK package), and install CDT online.

UCK stands for Ubuntu Customization Kit: https://launchpad.net/uck

We can use PPA to install it:

And you’ll find it in under “System Tools” section of your menu. Follow the wizard to create your own Ubuntu image. It will extract your Ubuntu image, and also the squashfs on it. 5G free disk space is required under ~/tmp. The final customized image locates as ~/tmp/remaster-new-files/livecd.iso.

I tried to use a 10.04.4 image as base image. It ends with message:

Don’t worry. The final image is already created. isohybrid is in syslinux package 3.72 and later. But Ubuntu 10.04 has only 3.63.

Now you can use the image like the source image. Either burn it or use it to install from harddisk. I integrated all Chinese supports, codecs and some development tools. See screenshot of my livecd:

ubuntu_uck