getnameinfo() compile time error - Extracting MAC address in Linux - c++

I have to send to the server the IP address and MAC address of the network interface from which my client socket is connected and communicating with the server.
All machines are on intra-net.
I have extracted the IP of my socket and I am attempting to extract the H/W address.
My strategy :
Extract IP of the socket using getsockname() system call.
Use getifaddrs() system call to list all available network interfaces. Inside a for-loop I am using getnameinfo() system call to find IP for currently iterating interface name and then compare this IP with socket IP (extracted from step 1) to find interface name of the connected socket.
Use ioctl(fd, SIOCGIFHWADDR, &ifr) system call to get H/W address using interface name found out in stage 2.
I am facing problem getnameinfo() system call.
If I don't type cast the first parameter to (struct sockaddr_in*) I get the following error : ai_family not supported
getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in), host, NI_MAXHOST,
NULL, 0, NI_NUMERICHOST);
If I type cast the first parameter to (struct sockaddr_in*) I get the following error : error: cannot convert ‘sockaddr_in*’ to ‘const sockaddr*’ for argument ‘1’ to ‘int getnameinfo(const sockaddr*, socklen_t, char*, socklen_t, char*, socklen_t, int)’
getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in), host, NI_MAXHOST,
NULL, 0, NI_NUMERICHOST);
Kindly advice. I am even open to some alternative strategy to programmatically and dynamically get Socket IP and MAC address.
bool Ethernet::getIp(void)
{
struct sockaddr_in addr;
char bufferIp[INET_ADDRSTRLEN];
socklen_t addrLen = sizeof(addr);
if(getsockname(this->clientSocket, (struct sockaddr*) &addr, &addrLen) == -1)
{
string errStr = strerror(errno);
FileOperations fo;
string str;
str = "Unable to extract IP address of socket";
str += " Error : " + errStr;
fo.printError(str);
return RETURN_FAILURE;
}
if(inet_ntop(AF_INET, &addr.sin_addr, bufferIp, INET_ADDRSTRLEN) == NULL)
{
string errStr = strerror(errno);
FileOperations fo;
string str;
str = "Unable to convert extracted IP address from binary to char* in Ethernet::getInterfaceDetails.";
str += " Error : " + errStr;
fo.printError(str);
return RETURN_FAILURE;
}
this->ip = string(bufferIp);
return RETURN_SUCCESS;
}
bool Ethernet::getMac(void)
{
int fd;
struct ifreq ifr;
// char *iface = "eth0";
unsigned char *mac;
fd = socket(AF_INET, SOCK_DGRAM, 0);
ifr.ifr_addr.sa_family = AF_INET;
strncpy(ifr.ifr_name , this->interfaceName.c_str(), IFNAMSIZ-1);
ioctl(fd, SIOCGIFHWADDR, &ifr);
close(fd);
mac = (unsigned char *)ifr.ifr_hwaddr.sa_data;
//display mac address
printf("Mac : %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n" , mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
return RETURN_SUCCESS;
}
bool Ethernet::getInterfaceDetails(void)
{
struct ifaddrs *ifaddr, *ifa;
int s;
char host[NI_MAXHOST];
string tempAddr;
char buffer[INET_ADDRSTRLEN];
if (getifaddrs(&ifaddr) == -1)
{
string errStr = strerror(errno);
FileOperations fo;
string str;
str = "System call 'getifaddrs' failed in Ethernet::getInterfaceDetails.";
str += " Error : " + errStr;
fo.printError(str);
return RETURN_FAILURE;
}
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
{
if (ifa->ifa_addr == NULL)
continue;
this->interfaceName = string(ifa->ifa_name);
if(this->interfaceName == string("lo"))
continue;
s = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in), host, NI_MAXHOST,
NULL, 0, NI_NUMERICHOST);
if(s != 0)
{
string errStr = gai_strerror(s);
cout << "Error : " << errStr << endl;
FileOperations fo;
string str;
str = "Unable to convert extracted IP address address from binary to char* in Ethernet::getInterfaceDetails.";
str += " Error : " + errStr;
fo.printError(str);
return RETURN_FAILURE;
}
tempAddr = string(host);
if(tempAddr == this->ip)
{
freeifaddrs(ifaddr);
return RETURN_SUCCESS;
}
}
return RETURN_FAILURE;
}

I see one strange thing regarding your call to getnameinfo: You are assuming that a non-null ifa_addr equals sockaddr_in type, but I could imagine you could get other types, e.g. sockaddr_in6. So you should check ifa_addr->sa_family field to make sure it's AF_INET. Perhaps you should handle IPv6 as well?
My theory here is that calling getnameinfo with a struct size that does not match what would be expected for the address family might be the reason for your error.
Also look at MAC address with getifaddrs for a related discussion.

The getifaddrs manual says
The ifa_addr field points to a structure containing the interface address. (The sa_family subfield should be consulted to determine the format of the address structure.) This field may contain a null pointer.
Thus
check that the field is not a null pointer (if it is, then it is not the IP you're looking for)
the length parameter must match the length of the addresses in sa_family / or filter just AF_INET.
But wouldn't it be easier to just create a datagram socket to the server then ask what's its address, or actually do the http connection and ask what mac address that socket is using?
If this is embedded Linux and the interface is always named the same, just read from /sys/class/net/eth0/address - much easier.

#Antti Haapala, #Mats;
Thanks for the help.
The problem was as you mentioned that other types/families of addresses where present in the interfaces and where causing problems to getnameinfo() system call.
Now I am filtering out other addresses and only allowing AF_INET.
I have added the following validation :
if(ifa->ifa_addr->sa_family != AF_INET)
continue;

Related

C/C++ getnameinfo ai_family not supported only on macOS

the following code does not work on macOS anymore if IPv6 or some virtual interfaces are available.
i got always the error getnameinfo() failed: Unknown error (ai_family not supported)
any idea whats wrong with this? i only need a correct network interface with ipv4 and internet.
The problem first appeared with macOS Sierra.
#include "jni.h"
#include "bla_nativeclasses_JNISubNetMask.h"
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netdb.h>
#include <ifaddrs.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
static jobjectArray make_row(JNIEnv *env, jsize count, const char* elements[])
{
jclass stringClass = (*env)->FindClass(env, "java/lang/String");
jobjectArray row = (*env)->NewObjectArray(env, count, stringClass, 0);
jsize i;
for (i = 0; i < count; ++i) {
(*env)->SetObjectArrayElement(env, row, i, (*env)->NewStringUTF(env, elements[i]));
}
return row;
}
JNIEXPORT jobjectArray JNICALL Java_bla_JNISubNetMask_getSubNetMask(JNIEnv *env, jobject jobj){
struct ifaddrs *ifaddr, *ifa;
int family, s ,s2;
int i = 0;
int count = 0;
char host[NI_MAXHOST];
char subnet[NI_MAXHOST];
char *tmp = NULL;
const char* net[1000];
if (getifaddrs(&ifaddr) == -1) {
perror("getifaddrs");
exit(EXIT_FAILURE);
}
/* Walk through linked list, maintaining head pointer so we can free list later */
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
if (ifa->ifa_addr == NULL)
continue;
if (ifa->ifa_addr->sa_family != AF_INET)
continue;
s = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
s2 = getnameinfo(ifa->ifa_netmask, sizeof(struct sockaddr_in), subnet, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
if (s != 0 || s2 != 0) {
printf("getnameinfo() failed: %s (%s)\n", gai_strerror(s), gai_strerror(s2));
exit(EXIT_FAILURE);
}
tmp = (char *)malloc(100*sizeof(char));
strcpy (tmp,ifa->ifa_name);
net[i++] = tmp;
tmp = (char *)malloc(100*sizeof(char));
strcpy (tmp,host);
net[i++] = tmp;
tmp = (char *)malloc(100*sizeof(char));
strcpy (tmp,subnet);
net[i++] = tmp;
}
freeifaddrs(ifaddr);
count = i;
jobjectArray jnet = make_row(env, count, net);
return jnet;
}
I know that there was already another similar question, but I don't really understand the answer
The problem is occurring because IPV4 and IPV6 have different sizes. Consider the following two lines of your code
s = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
s2 = getnameinfo(ifa->ifa_netmask, sizeof(struct sockaddr_in), subnet, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
the sizeof operation will work fine for your code if the address familyis AF_INET, but for IPV6 aka AF_INET6 you have to use sizeof(sockaddr_in6);, they both have different size (4 and 6 bytes respectively).
what you can do is the following -
int len;
switch (fa->ifa_addr->sa_family) {
case AF_INET:
len = sizeof(sockaddr_in);
break;
case AF_INET6:
len= sizeof(sockaddr_in6);
break;
default:
std::cerr << "Unknown Address family\n";
break;
}
then use the length on you call to getnameinfo.
EDIT
#leo_poldX, It seems because of if (ifa->ifa_addr->sa_family != AF_INET)
continue;, the rest of code should not execute for IPV6. Can you check if it is correct?
i got always the error getnameinfo() failed: Unknown error (ai_family not supported)
Based on the origin of that message in your code, it seems clear that it arises from a case where
s2 = getnameinfo(ifa->ifa_netmask, sizeof(struct sockaddr_in), subnet, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
fails with error code EAI_FAMILY, even though the immediately preceding
s = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
succeeded. Based on the specific error code, the failure probably arises from ifa->ifa_netmask->ai_family being set to a value different from AF_INET, either
a different, known family whose addresses require a larger address structure, or
an invalid / unknown family.
I can imagine ways in which either one might arise, but either way, I would characterize it as a bug for getifaddrs() to return any entry in which the address and netmask were drawn from different address families.
Plausible mitigations depend on the specific nature of the problem. For example,
if the overall entry is simply invalid then you should detect that and skip it.
if the netmask data are in the form of an IPv4 address, but the system has failed to set the family [correctly] then you could try to detect that case and correct it before calling getnameinfo().
if the netmask is in the form of an IPv6 address, then you could detect that and read it as an IPv6 address, and figure out where to go from there. It might be that the result is an IPv4 address encoded as an IPv6 address, in which case you could extract the former from the latter.
if you can do without the subnet mask, then you could just dummy it up in this case, or perhaps even remove it from the method result altogether.

How to add entry in Neighbour Table in IPV6 in linux using C/C++ Code?

For IPV4, I have added the Neighbour entries in this way.
'''
void assocArp(string ipAddress, const uint8_t * const macAddress, char_t interface[])
{
int32_t sockfd;
struct arpreq req;
struct sockaddr_in *ptrSin;
char_t device[20];
(void)memcpy(device, interface, IFNAMSIZ);
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0) {
cout << "\n assocArp : Failure in AF_INET socket opening in assocArp in
IPService\n";
return;
}
(void)memset((char_t *) &req, 0, sizeof(req));
// Adding required IP Address to req structure
ptrSin = (struct sockaddr_in *)&req.arp_pa;
ptrSin->sin_family = AF_INET;
ptrSin->sin_addr.s_addr = inet_addr(ipAddress.c_str());
// Adding required MAC address to req structure
(void)memcpy(req.arp_ha.sa_data, macAddress, 6);
req.arp_flags = ATF_PERM | ATF_COM;
(void)memcpy(req.arp_dev, device, IFNAMSIZ);
if (ioctl(sockfd, SIOCSARP, (caddr_t)&req) < 0) {
cout << "ARP assoc set failed" << endl;
cout << "\nException caught : ioctl Failure in assocArp function in
IPService\n";
(void)close(sockfd);
return;
}
close(sockfd);
}
'''
In case of IPV6 the structure "struct arpreq req" can't be used & i am unable to find any alternative structure for ipv6.
Can anyone suggest something about how to implement the functionality to enter Neighbour Entry in IPV6?
ARP protocol is limited to IPv4. In IPv6, MAC address resolution is handled by the Neighbor Discovery Protocol (a.k.a. ndisc).
In Linux, the easiest is to use the rtnetlink API for interfacing with ndisc; RTM_NEWNEIGH, RTM_DELNEIGH, RTM_GETNEIGH commands can be used to add, delete or query the neighbor table.
See the source of iproute2/ip/iproute.c for an example usage.

WinSock2: connect() delivers 'connection refused'

I have been trying to get a simple SFTP program working with code from this website, but I have not been able to get it to even send out data without it returning error code 10061 (WSAECONNREFUSED). I have tried using Wireshark on the active interface with all firewalls disabled, but it didn't say anything was being sent to the address I gave (ex: 72.196.212.127). However, when I give it a local address like 192.168.1.101, it gives error code 10060 (WSAETIMEDOUT), still not sending out any data on the network. I am able to connect to the target machine on both address with software like Putty and WinSCP and ping it on the command prompt.
Here is the relevant part of my connection method:
// Open socket
WSADATA data;
int err = WSAStartup(MAKEWORD(2, 0), &data);
if (err != 0) return "ERROR: Failed to initialize WSA";
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(port);
sin.sin_addr.s_addr = to_uint32_t(ip);
if (net::connect(sock, (struct sockaddr*) &sin, sizeof(struct sockaddr_in)) != 0) return "ERROR: Could not connect to host. Code: " + std::to_string(WSAGetLastError());
The variable port is an integer (value = 22), with ip being a string (192.168.1.101 or 72.196.212.127). This function returns the "Could not connect to host" error. No other errors occur.
Here is the to_uint32_t method:
std::uint32_t to_uint32_t(const std::string& ip_address)
{
const unsigned bits_per_term = 8;
const unsigned num_terms = 4;
std::istringstream ip(ip_address);
uint32_t packed = 0;
for (unsigned i = 0; i < num_terms; ++i)
{
unsigned term;
ip >> term;
ip.ignore();
packed += term << (bits_per_term * (num_terms - i - 1));
}
return packed;
}
#selbie pointed out that I was not using the correct function for resolving the IP. To fix my code, I just switched sin.sin_addr.s_addr = to_uint32_t(ip); to inet_pton(AF_INET, ip, &sin.sin_addr);.

Creating an IPv6 Socket failed with invalid IP - seems to get truncated

I am currently learning C++ and I'm working on a library that will allow sockets to be created on Windows and Linux, supporting IPv4 and IPv6.
I've got it working fine on IPv4 but I'm having a problem with IPv6.
I've tried doing it so it binds to an IP address or binds to a specific IPV6 address but either fail.
Below is how I create a socket.
this->serverSocket = socket(family, socketType, 0);
if (this->serverSocket < 0)
{
stringstream logstream;
logstream << "Error opening socket. Most likely trying to bind to an ";
logstream << "invalid IP or the port is already in use";
bitsLibrary->writeToLog(logstream.str(), "LinuxSocket", "createSocket");
return false;
}
switch (family)
{
case AF_INET: {
this->serv_addr = new sockaddr();
bzero((sockaddr*)this->serv_addr, sizeof(this->serv_addr));
sockaddr_in *sin = reinterpret_cast<sockaddr_in*>(serv_addr);
sin->sin_family = family;
//sin->sin_addr.s_addr = INADDR_ANY;
//If IP Address is NULL then set to IPADDR_ANY
if (ipAddress.empty())
{
sin->sin_addr.s_addr = INADDR_ANY;
}
else
{
inet_pton(AF_INET, ipAddress.c_str(), &sin->sin_addr);
}
sin->sin_port = htons(port);
break;
}
case AF_INET6: {
this->serv_addr = new sockaddr();
bzero((sockaddr*)this->serv_addr, sizeof(this->serv_addr));
sockaddr_in6 *sin = reinterpret_cast<sockaddr_in6*>(serv_addr);
sin->sin6_family = family;
if (ipAddress.empty())
{
sin->sin6_addr = IN6ADDR_ANY_INIT;
}
else
{
inet_pton(AF_INET6, ipAddress.c_str(), &(sin->sin6_addr));
}
sin->sin6_port = htons(port);
break;
}
default:
this->bitsLibrary->writeToLog("Invalid socket family. Only AF_INET or AF_INET6 is supported");
return false;
}
Below is how I then bind the socket
stringstream logstream;
int result = bind(this->serverSocket, (sockaddr * )serv_addr, sizeof(*serv_addr));
if (result < 0)
{
logstream << "Failed to bind socket. Error: " << strerror(result);
throw SocketException(logstream.str().c_str());
close(this->serverSocket);
return false;
}
result = listen(this->serverSocket, this->socketPort);
if (result < 0)
{
logstream << "Failed to start listening. Socket Error: " << strerror(result);
throw SocketException(logstream.str().c_str());
}
logstream << "Socket " << this->socketPort << " has been successfully bound";
this->bitsLibrary->writeToLog(logstream.str(), "LinuxSocket", "bindAndStartListening");
return true;
I call the create socket function as follows
if (!socketManager.createSocket(AF_INET6, SOCK_STREAM, 500, 50, "fe80::20c:29ff:fea0:7da8"))
The bind returns -1 strerror says an unknown error occurred.
The IP address that I am passing into createSocket method is fe80::20c:29ff:fea0:7da8.
When I run my program through strace I then get the following on the bind
socket(PF_INET6, SOCK_STREAM, IPPROTO_IP) = 4
bind(4, {sa_family=AF_INET6, sin6_port=htons(500), inet_pton(AF_INET6, "fe80::", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, 16) = -1 EINVAL (Invalid argument)
Notice that the IP has been truncated to fe80::.
If I don't use an IP so it binds to anything the IP is then ::
Update
Below is the code I have changed for the AF_INET6 socket.
case AF_INET6: {
this->serv_addr = new sockaddr_storage();
bzero((sockaddr_in6*)this->serv_addr, sizeof(this->serv_addr));
sockaddr_in6 *sin = reinterpret_cast<sockaddr_in6*>(serv_addr);
sin->sin6_family = family;
if (ipAddress.empty())
{
sin->sin6_addr = IN6ADDR_ANY_INIT;
}
else
{
inet_pton(AF_INET6, ipAddress.c_str(), &sin->sin6_addr);
}
sin->sin6_port = htons(port);
break;
}
I've also change this->servAddr is sockaddr_storage in the header as suggested
At least on Windows, sizeof(sockaddr) < sizeof(sockaddr_in6). When you allocate memory for this->serv_addr, you allocate not enough, then corrupt your heap block, and then you have bugs.
It's suggested that you use sockaddr_storage which is "Large enough to accommodate all supported protocol-specific address structures". Or you can allocate different structures in different cases, which shouldn't be a problem for the rest of your code.
UPDATE 1
There still seems to be a few mistakes in your code. You need to check all references to this->serv_addr and verify types/sizeof's.
-- Example 1: You bzero() a wrong number of bytes here - not only a wrong sizeof of wrong type, but also you do sizeof on a pointer:
bzero((sockaddr_in6*)this->serv_addr, sizeof(this->serv_addr));
Should be fixed like that:
sockaddr_in6 *sin = reinterpret_cast<sockaddr_in6*>(serv_addr);
bzero(sin, sizeof(*sin));
-- Example 2: You pass wrong buffer size here:
int result = bind(this->serverSocket, (sockaddr * )serv_addr, sizeof(*serv_addr));
You should remember the actual size for this->serv_addr at the time you allocate it and pass this size to bind()

Conversion of IPv6 to IPv4 gives 0.0.0.1 only

I am writing a Java interposer (using LD_PRELOAD method) that modifies the recipient information in network communication system calls (connect/sendto).
Whenever Java tries to connect to another socket, I modify the intended recipient IP and port. Java uses IPv4-mapped-IPv6 addresses. So, I need to extract the IPv4 part of it. I achieve this using the method prescribed by Nicolas Bachschmidt at link.
The problem I am facing is that for every IPv4-mapped-IPv6 address, the result string (IPv4 part) I obtain is always 0.0.0.1. Instead it should be 10.0.0.1 (for ::ffff:10.0.0.1). I have tried this with different IP addresses. The result is always the same.
Two things I would like to mention that I think may be related:
When I tested the same program a month ago on my local network (that has 192.168.1.XXX IP addresses), the program worked correctly. Point being (I don't think) there is any problem with code. To verify this, I asked a question on stackoverflow to convert IPv4-mapped-IPv6 addresses to IPv4, the link of which is mentioned earlier).
I am trying to test this program now on my university network (that has 10.XXX.XXX.XXX IP addresses) and VirtualBox (NAT mode that also gives 10.XXX.XXX.XXX addresses). However, I have tried to connect to 10.0.0.1 and 12.0.0.1 in these cases. Both give 0.0.0.1.
What am I doing wrong?
UPDATE: In Java, socket connection is done by the usual method:
Socket conn = new Socket("10.0.0.1", 50021);
The code to interpose this connect() system call is as follows:
int connect(int fd, const struct sockaddr *sk, socklen_t sl)
{
struct sockaddr_in *lsk_in = (struct sockaddr_in *) sk;
struct sockaddr_in6 *lsk_in6 = (struct sockaddr_in6 *) sk;
struct sockaddr_in addr4;
unsigned int len;
int nbytes, oport, tport, ret, i;
char ip_address[30];
char buffer[1024];
char tempBuffer[1024];
if((lsk_in->sin_family == AF_INET) || (lsk_in->sin_family == AF_INET6))
{
if(lsk_in->sin_family == AF_INET)
{
oport = ntohs(lsk_in->sin_port);
memcpy(&addr4.sin_addr.s_addr, &lsk_in->sin_addr.s_addr, sizeof(addr4.sin_addr.s_addr));
}
else if(lsk_in->sin_family == AF_INET6)
{
oport = ntohs(lsk_in6->sin6_port);
//This is where the problem is. I always get 0.0.0.1
memcpy(&addr4.sin_addr.s_addr, lsk_in6->sin6_addr.s6_addr+12, sizeof(addr4.sin_addr.s_addr));
}
memset(buffer, '\0', sizeof(buffer));
sprintf(buffer, "%s%c%s%c%i", NAT_VM_CONNECT_RULE, NAT_VM_DELIMITER, (char *)inet_ntoa(addr4.sin_addr), NAT_VM_DELIMITER, oport);
nbytes = send(sock, buffer, strlen(buffer), 0);
if(DEBUG_MODE)
fprintf(stdout, "[LD_INTERPOSER] Sent[%s]\n", buffer);
memset(buffer, '\0', sizeof(buffer));
nbytes = recv(sock, buffer, sizeof(buffer), 0);
fprintf(stderr, "[LD_INTERPOSER] Received CONNECT [%s]\n", buffer);
memset(ip_address, '\0', sizeof(ip_address));
int pos = strrchr(buffer, NAT_VM_DELIMITER) - buffer;
strncpy(ip_address, buffer, pos);
ip_address[pos] = '\0';
tport = atoi(buffer + pos + 1);
if(lsk_in->sin_family == AF_INET)
{
lsk_in->sin_addr.s_addr = inet_addr(ip_address + 7);
lsk_in->sin_port = htons(tport);
}
else if(lsk_in->sin_family == AF_INET6)
{
inet_pton(AF_INET6, ip_address, &(lsk_in6->sin6_addr));
lsk_in6->sin6_port = htons(tport);
}
fprintf(stderr, "[LD_INTERPOSER] IP[%s], Port[%d] for VM[%s]\n", ip_address, tport, vm_ip);
}
return real_connect(fd, sk, sl);
}
Thanks to #ugoren hex dump technique (in comments), I was able to figure out that the IPv6 structure itself contained a 0.0.0.1 address. I realized that the problem may be due to different JDKs. The Java project was built using OpenJDK 7 while the PC I was using had OpenJDK 6. When I updated the JDK to version 7, the error disappeared. However, it has landed me to another error which is documented at a new stackoverflow question which I am still unable to resolve.