<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Crack in the River</title>
	<atom:link href="http://crackintheriver.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://crackintheriver.wordpress.com</link>
	<description>Just another WordPress.com weblog</description>
	<lastBuildDate>Mon, 16 Jul 2007 13:02:13 +0000</lastBuildDate>
	<generator>http://wordpress.com/</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<cloud domain='crackintheriver.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://www.gravatar.com/blavatar/b49d53d985d3a1a032c688f736a2a362?s=96&#038;d=http://s.wordpress.com/i/buttonw-com.png</url>
		<title>Crack in the River</title>
		<link>http://crackintheriver.wordpress.com</link>
	</image>
			<item>
		<title>ioctl interface settings</title>
		<link>http://crackintheriver.wordpress.com/2007/07/16/ioctl-interface-settings/</link>
		<comments>http://crackintheriver.wordpress.com/2007/07/16/ioctl-interface-settings/#comments</comments>
		<pubDate>Mon, 16 Jul 2007 13:00:27 +0000</pubDate>
		<dc:creator>Silver</dc:creator>
				<category><![CDATA[Libnet De-assembled]]></category>

		<guid isPermaLink="false">http://crackintheriver.wordpress.com/2007/07/16/ioctl-interface-settings/</guid>
		<description><![CDATA[Hey *myself* *chuckles*,
Well, as I promised, I bring you another post of nothing interesting, and this time, even I ain&#8217;t interested. But I thought that this experiment was necessary, to make sure that we are all comfortable with using ioctl for the interface.
But before that, another thing. You guys would be inspired to write codes [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=crackintheriver.wordpress.com&blog=1341848&post=8&subd=crackintheriver&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Hey *myself* *chuckles*,<br />
Well, as I promised, I bring you another post of nothing interesting, and this time, even I ain&#8217;t interested. But I thought that this experiment was necessary, to make sure that we are all comfortable with using ioctl for the interface.<br />
But before that, another thing. You guys would be inspired to write codes like me (kudos), well don&#8217;t. Yeah, indent, and name ur vars properly, thats me, but ALWAYS error check, especially when calling library functions which might have a damn good chance of returning errors. I leave the error writing to your part, mainly cause I want to make my code concise, and filled with what I want. Never ever, however in reality, go without error checking!</p>
<p><em>A little personal (please skip)</em>:<br />
Well, today, went to watch this movie, naqaab, and it sucked on ice, atleast, thats what I felt. Other than that, when I came back from movie, I was chatted 2 by 6 people simultaneously, whao is me! And lastly, some1 called anuda met me on orkut today, and I &#8220;guess&#8221; that she knows quite alot&#8230; for some1 who knows asm, I think C advanced is a pre-requisite. Plus, she&#8217;s a student, so not a network professional like susam or sudeep. Yeah, there&#8217;s vipul, he&#8217;s cool and all, but we engage in different styles of security. Lets see what frequency is anuda @.<br />
Oh, and another thing, I am searching for some1 to help me write articles for my blog&#8230; just for the fun of it. Right now, I know, I am the only 1 who reads and writes it, but I hope that in future, when I get time to SEO, the blog will really come up, as it deals with a very rare subject.</p>
<p><em>Back to the code</em>:<br />
Well, this code is just a whole lot of ioctl&#8217;s all put together into one code, to get complete information about the interface. Its quite documented, and the principles and stuff are already explained in the previous entries.<br />
<code><br />
//self_interfaceall.c - Get complete information about interfaces<br />
//Yup, made by me, Gaurav aka Silver<br />
#include "libnethead.h"<br />
#define MAXADDR 10<br />
//Just an array for max ip addresses<br />
//For some reason, cannot make this allocate dynamically.... If we do, then we don't get any interfaces reported?<br />
//Asked devsheds, lets see what happens.<br />
int main(){<br />
int fd;<br />
int flags,i;<br />
struct ifreq *ifr,*ifend;<br />
struct ifreq ifmax[MAXADDR];<br />
struct ifconf iflist;<br />
struct sockaddr_in sin;<br />
char buffer[25],devname[IFNAMSIZ];<br />
struct ether_addr ea;<br />
memset(&amp;buffer,0,25);<br />
fd=socket(AF_INET,SOCK_DGRAM,0);<br />
//dummy socket, but created on IPv4 (note). Sock type isnt as important as the protocol family<br />
//For this call, which gets the number of interfaces, ifc_req/ifc_buf MUST be 0<br />
if(ioctl(fd,SIOCGIFCONF,(char*)&amp;iflist)&lt;0){ printf("ioctl failed for SIOCGIFCONF"); exit(0); }<br />
//We know that my machine doesnt have sa_len , so skip that char buffer stuff<br />
printf("Total number of interfaces: %d\n\n",(iflist.ifc_len)/sizeof(struct ifreq));<br />
iflist.ifc_req=ifmax;  //Put the interface list in a large enough location.<br />
if(ioctl(fd,SIOCGIFCONF,(char*)&amp;iflist)&lt;0){ printf("ioctl failed for SIOCGIFCONF"); exit(0); }<br />
ifr=iflist.ifc_req;   //These lines for traversing the array<br />
ifend=(struct ifreq *)(iflist.ifc_buf+iflist.ifc_len);<br />
for(;ifrifr_name);<br />
strncpy(devname,ifr-&gt;ifr_name,sizeof(ifr-&gt;ifr_name)); //Store it just for now<br />
//Get the flags<br />
printf("The device is: "); //Get the flags<br />
if(ioctl(fd,SIOCGIFFLAGS,(char*)ifr)ifr_flags;<br />
if(flags &amp; IFF_UP){ printf("Up "); }<br />
if(flags &amp; IFF_LOOPBACK){ printf("Loopback "); }<br />
if(flags &amp; IFF_BROADCAST){ printf("Broadcast_supported "); }<br />
if(flags &amp; IFF_MULTICAST){ printf("Multicast_supported"); }<br />
printf("\n"); if(flags &amp; IFF_LOOPBACK) continue;  //We cant get the hwaddr and stuff for loopback<br />
//Get the ip address-<br />
if(ioctl(fd,SIOCGIFADDR,(char*)ifr)ifr_addr));<br />
inet_ntop(AF_INET,&amp;(sin.sin_addr.s_addr),buffer,INET_ADDRSTRLEN);<br />
printf("IP Address: %s\n",buffer);<br />
if(flags &amp; IFF_BROADCAST){ //find the broadcast address, if it exists<br />
if(ioctl(fd,SIOCGIFBRDADDR,(char*)ifr)ifr_broadaddr));<br />
inet_ntop(AF_INET,&amp;(sin.sin_addr.s_addr),buffer,INET_ADDRSTRLEN);<br />
printf("Broadcast Address: %s\n",buffer);<br />
}<br />
//Now get the hardware address<br />
if(ioctl(fd,SIOCGIFHWADDR,(char*)ifr)ifr_hwaddr.sa_data),6);<br />
printf("Hardware Address: ");<br />
for(i=0;i&lt;6;i++){  //This is the normal printing, I told in the last blog entry.<br />
sprintf(buffer,"%x",ea.ether_addr_octet[i]);<br />
if(strlen(buffer)&lt;2){ printf("0"); }<br />
printf("%s",buffer);<br />
if(i!=5) printf(":");<br />
}<br />
printf("\n");<br />
}<br />
return 0;<br />
}<br />
</code></p>
<p>Yeah, just compile that code, and run it&#8230; It should return the interfaces present, as well as their states&#8230; Feel free to add extra stuff if needed or applicable, such masters and slaves (for load balancers), and etc. That one code should be enough for a somewhat thorough understanding of using ioctl&#8217;s with the network interface devices.</p>
<p><em>Code 2</em>:<br />
Now we try and do something different. All this while, we just queried and found out about network devices, but now, we are going to set them&#8230;. In general, the steps for SIOC&#8230;.. are-<br />
1. To get devices, set ifr.ifr_name string to the device name, and all the other fields can contain any value, including blank. Then, call ioctl, with the appropriate request and (char*) pointer to the ifreq object (except in case of SIOCGIFCONF). In that call, ifreq object gets modified and the appropriate member of the union will have the corresponding data that is needed. All these requests begin with SIOCGIF___ , S for sumthing, IO probably interface, C, dunno&#8230;. G is probably for GET, and IF for interface.<br />
2. To set device characteristics, set ifr.ifr_name string to the device name, but this time, set the appropriate union member in ifreq object to the new value which you want to set to&#8230;. Then call the ioctl command with the request and argument&#8230; if successful, ioctl wouldnt return -1, and that way, you know that the parameter has been changed successfully. All these requests begin with SIOCSIF___, that latter S probably standing for &#8220;set&#8221;</p>
<p><em>Note:</em><br />
One more thing I found out, from mailing lists of tcpdump. In linux, there are something called flags and gflags associated with the device, which specify its operation. While setting device flags with ioctl, only the &#8220;gflags&#8221; field is set. Whereas, setting the flags using setsockopt() (yeah, you can set characteristics of the socket/interface with setsockopt as well, right), only the &#8220;flags&#8221; field is set, but not the &#8220;gflags&#8221;.<br />
Now, there is one more difference. When we set a flag with socksetopt() , with socket SOL_PACKET, and request type as PACKET_ADD_MEMBERSHIP (dont worry, all this coming soon), and the binding to put in promiscious mode, PACKET_MR_PROMISC, we can put the device in promiscious mode as well. But in this case, the kernel associates this with the socket, and hence keeps track of which process put the device in promiscious mode. So, when the socket closes, the device is put back to the normal state (as stored in the gflags field), if there is not another socket thats using it.<br />
What i mean is that, consider A process starts, puts the device in promiscious mode (using setsockopt). Now, B starts, and using setsockopt, decides to put the socket in promiscious mode as well (which it already is in). Now, A stops&#8230; In this case, the kernel keeps track of the request to set device in promiscious mode, and hence, since B is using that mode, it doesnt shut it off&#8230; However, if A put the device using flags IFF_PROMISC and ioctl, to first put, and then remove the promiscious mode, then even if B uses that mode, the mode will be shut off when A shuts off.<br />
Hence, it is advisable to normally use setsockopt for promiscious mode setting, or flag setting. However, ioctl&#8217;s sometimes offer more flexibility.</p>
<p><em>The code (finally):</em><br />
Again, I believe well commented, and explains the general method for doing these sortof things.<br />
<code><br />
//self_interfacechange.c - Attempts to change characteristics of the interface <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
//Yup, guessed it right, its made by Silver, aka Gaurav <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /><br />
#include "libnethead.h"<br />
#define device "eth0"<br />
#define newip "172.16.38.53"<br />
//Earlier IP address was .52<br />
int main(){<br />
int fd;<br />
char flagset=0;<br />
struct ifreq ifr;<br />
struct sockaddr_in sin;<br />
struct ether_addr ea={0x00,0x16,0x36,0x7b,0xa6,0x0a}; //Last change from 0b to 0a<br />
strcpy(ifr.ifr_name,device); //The thing that gonna be the info source.<br />
//First, lets change the mac address .<br />
fd=socket(PF_INET,SOCK_DGRAM,0);<br />
memcpy(&amp;(ifr.ifr_hwaddr.sa_data),&amp;ea,6); //Load the hard ware address.<br />
ifr.ifr_hwaddr.sa_family=ARPHRD_ETHER; //Forgot this earlier.<br />
if(ioctl(fd,SIOCSIFHWADDR,(char*)&amp;ifr)&lt;0){ printf("Error. Unable to change\n");  exit(0); }<br />
printf("Changed ethernet address\n");<br />
//Now change the IP address.<br />
memset(&amp;sin,0,sizeof(struct sockaddr_in));<br />
sin.sin_family=AF_INET; if(inet_pton(AF_INET,newip,&amp;sin.sin_addr)&lt;0){ printf("error\n"); exit(0); }<br />
//port should be zero<br />
ifr.ifr_addr=*(struct sockaddr *)&amp;sin;<br />
if(ioctl(fd,SIOCSIFADDR,(char*)&amp;ifr)&lt;0){ printf("Error. Unable to change\n");  exit(0); }<br />
printf("Changed ip address\n");<br />
//Put off the device.<br />
if(ioctl(fd,SIOCGIFFLAGS,(char*)&amp;ifr)&lt;0){ printf("Error. Unable to get flags\n"); exit(0); }<br />
ifr.ifr_flags=ifr.ifr_flags&amp;(~IFF_UP); //Disables device<br />
//ifr.ifr_flags=ifr.ifr_flags | IFF_UP; //Enable device (heh, I knew I had to include this <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  )<br />
if(ioctl(fd,SIOCSIFFLAGS,(char*)&amp;ifr)&lt;0){ printf("Error. Unable to set flags\n"); exit(0); }<br />
printf("Flags set\n");<br />
return 0;<br />
}<br />
</code><br />
As you can well see, there are 3 objectives of this code: 1. To change the Hardware address, 2. To change the IP address, 3. To put off/on the device.<br />
You may change the code as you wish, all 3 parameters. Just run it, and if you&#8217;re lucky (or smart), the code will give 3 success messages! Yup, you are set. To test whether the script really was successful, just run the first code, self_interfaceall . W00T, your all set!</p>
<p><em>Post-face</em>:<br />
Well, what else would you it, ya? Well, the code I wrote was probably comprehensive enough for explaining all the concepts that were developed till now&#8230; From now on, we won&#8217;t lay any special importance to getting or setting interface name/characteristics. Just note, that to change the name of the device, simply fill in ifr.ifr_name with the new name, and ifr.ifr_ifindex with the previous index&#8230; see, this parts a bit different. And thats about the end of our special discussion of ioctl&#8217;s for getting interface details.</p>
<p><em>Whats next:</em><br />
Well, I said that I&#8217;d be forming the ethernet packet&#8230; However, I&#8217;m in confusion, &#8220;maybe&#8221; I might post about ethernet packets, or perhaps, I might post a bit about broadcasting and multicasting concepts in general and specific.<br />
If you&#8217;re not me, and your reading this blog, well, you&#8217;d be 1 of the rare ones <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  . This deals with quite a rare topic, so I hope that this blog comes up in search engines <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  .</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/crackintheriver.wordpress.com/8/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/crackintheriver.wordpress.com/8/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/crackintheriver.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/crackintheriver.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/crackintheriver.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/crackintheriver.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/crackintheriver.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/crackintheriver.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/crackintheriver.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/crackintheriver.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/crackintheriver.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/crackintheriver.wordpress.com/8/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=crackintheriver.wordpress.com&blog=1341848&post=8&subd=crackintheriver&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://crackintheriver.wordpress.com/2007/07/16/ioctl-interface-settings/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/19318262334355190171496b623c1704?s=96&#38;d=identicon" medium="image">
			<media:title type="html">silverlightning</media:title>
		</media:content>
	</item>
		<item>
		<title>Getting MAC Address- get_hwaddr</title>
		<link>http://crackintheriver.wordpress.com/2007/07/14/getting-mac-address-get_hwaddr/</link>
		<comments>http://crackintheriver.wordpress.com/2007/07/14/getting-mac-address-get_hwaddr/#comments</comments>
		<pubDate>Sat, 14 Jul 2007 05:38:22 +0000</pubDate>
		<dc:creator>Silver</dc:creator>
				<category><![CDATA[Libnet De-assembled]]></category>

		<guid isPermaLink="false">http://crackintheriver.wordpress.com/2007/07/14/getting-mac-address-get_hwaddr/</guid>
		<description><![CDATA[Hey *myself* *chucles*,
Well, its what I promised, finding out the ethernet address, and all I say is that its really quite lame. ah well, anyways, before we get into that, some other things I learnt (actually, learnt alot, but this is 1 of the newer more relevent things)-
Modifications to program:
Well, last time I posted a [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=crackintheriver.wordpress.com&blog=1341848&post=7&subd=crackintheriver&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Hey *myself* *chucles*,<br />
Well, its what I promised, finding out the ethernet address, and all I say is that its really quite lame. ah well, anyways, before we get into that, some other things I learnt (actually, learnt alot, but this is 1 of the newer more relevent things)-</p>
<p><em>Modifications to program</em>:<br />
Well, last time I posted a program that would give you the list of interfaces right? Well, there, I outputted the raw ip address, ie, the numerical host order ip address (yes, cause its getting it off the interface). So, here is the modification I made (you should know where it is, right?)-<br />
<code><br />
...<br />
int temp=(address_list[i].addr);<br />
char str[INET_ADDRSTRLEN+1];<br />
inet_ntop(AF_INET,&amp;(temp),str,INET_ADDRSTRLEN);<br />
prinf("Device: %s ,\t Address: %s\n",(address_list[i]).device,ipaddr);<br />
....<br />
</code><br />
Now compile the code and run it&#8230; Yup, you&#8217;d get a nice output of the IP address.<br />
Now, some of you might be asking: Hey, I thought IP address was at a higher layer, right? Well, ya, same doubt. But then I realised that ioctl fetches all the required information from that socket/interface. It doesnt depend on what level your asking. The socket file descriptor is associated with numerous things, like IP address, device hardware address, interface index (the device desriptor kinda, to the linux kernel), device name (human readable), etc. Btw, remember that this &#8220;ip address&#8221; which we get is the unicast IP address. It will be shown as a different ip address if the device is used in broadcast mode.</p>
<p><em>Modifications to my teaching style:</em><br />
Well, the version of libnet that I have in source is quite old really. And a really bad part is that till now, it was perhaps only source of information. But nope, not anymore <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  . I found a library on sourceforge, called libdnet, which does essentially similar things like libnet, except that libdnet is in active development, and actually has a working site backing it. So from now on, although I will still &#8220;de-assemble&#8221; libnet, I will use libdnet as a reference as well.</p>
<p><strong>De-assemble libnet_get_hwaddr</strong>:<br />
Pre-requisites are less. All that is known is that how to use ioctl SIOCGIFHWADDR, which is very similar to how we used SIOCGIFADDR to find the logical address associated with that interface socket.</p>
<p><em>Pre-requisite&#8217;d code:</em><br />
1. struct ether_addr definition: Although it isnt totally necessary, yet, its better we mention it anyways.<br />
struct ether_addr{<br />
u_int8_t ether_addr_octet[ETH_ALEN];<br />
}; //u_int8_t is a typedef of unsigned char.</p>
<p>Well, um&#8230; thats it. Other than that, the pre-requisites of the previous blog entry, ie, the ifreq structure.</p>
<p><em>Code Dissection</em><br />
<code>struct ether_addr *<br />
libnet_get_hwaddr(struct libnet_link_int *l, const u_char *device, char *ebuf)<br />
{</code><br />
The libnet_get_hwaddr accepts a &#8220;libnet_link_int&#8221; pointer&#8230; Well don&#8217;t worry, this thing is just retarded, cause its not used anywhere. You could well have passed an empty generic pointer cast to libnet_link_int . However, I suspect the reason for doing this. For future compatibility: The libnet_link_int contains the type of link layer protocol which could be used by the device. Perhaps, to make this function more generalised, this argument was passed, so that depending on the type of protocol used,  the corresponding hard ware address should be returned&#8230; probably for some future edition.<br />
As for the current moment, no, we don&#8217;t need it. So lets ignore it.</p>
<p><code>int fd;<br />
struct ifreq ifr;<br />
struct ether_addr *eap;<br />
/*<br />
*  XXX - non-re-entrant!<br />
*/<br />
static struct ether_addr ea;<br />
</code><br />
ifreq structure object ifr is used to query the kernel using the ioctl. It is the place where the result is returned. The ether_addr is a temporary object pointer, and it is passed back to the calling function (remember, the return value is a pointer). It gets its value from ifr object. The last struct ea is an object of ether_addr. The *eap is just a pointer to the ea object, kinda like an alias. ea is the name of da memory location. eap is just a pointer to it. So in the end, ea is returned back.<br />
<code><br />
/*<br />
*  Create dummy socket to perform an ioctl upon.<br />
*/<br />
fd = socket(AF_INET, SOCK_DGRAM, 0);<br />
if (fd &lt; 0)<br />
{<br />
sprintf(ebuf, "get_hwaddr: %s", strerror(errno));<br />
return (NULL);<br />
}<br />
</code><br />
The comments are appropriate. We need a sample socket to query for the ioctl, to act as the resource for ioctl. It could be of any type, even PACKET if we wanted it. Remember, btw, ideally, that AF_INET should be PF_INET, cause socket&#8217;s first argument is protocol family, not address family, but since 1 PF=1 AF, they are equivalent. In the end, just do some lame error checking to make sure that socket didnt fail (It won&#8217;t normally anyways)</p>
<p><code><br />
memset(&amp;ifr, 0, sizeof(ifr));<br />
eap = &amp;ea;<br />
strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));<br />
</code><br />
Just empty the ifr object in the first line&#8230; its always better to, before passing it off to ioctl. remember, that some members of the ioctl union are smaller than union max size, so if we don&#8217;t do this, some other part of the union might be filled by junk, so we will have problems if we try access other members of the union (which would be foolish, and 0&#8242;ing still won&#8217;t do much good <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  . Maybe its in case sockaddr is not filled completely ). The second line is just making sure that ea Pointer points to ea (I find this damn foolish really, oh well!). The last part seems trivial but is important. It copies the device name to the ifr obj. That way, ioctl realises which device&#8217;s hard ware address to find, resourced by the socket file descriptor (the socket file descriptor points to a number of devices, so this is a must). I doubt whether filling any other thing, like interface name would have the same effect (the union is prob Ignored while reading ifr object, since kernel doesnt know which information we provided. for eg, for 1 value of ifindex, the corresponding logical address might also be in a proper format, so kernel would be confused on which to operate. However, union filling would be done if you had to SET an hardware address, by SIOSGIFHWADDR (note the S instead of C), so the kernel knows where to look. Actually, this is what probably is done, right? Else how would u supply the new values anyways?)</p>
<p><code><br />
if (ioctl(fd, SIOCGIFHWADDR, (char *)&amp;ifr) &lt; 0)<br />
{<br />
close(fd);<br />
sprintf(ebuf, "get_hwaddr: %s", strerror(errno));<br />
return (NULL);<br />
}<br />
</code><br />
This is the code which does the main part. It gets the hard ware address. As always, ioctl takes the socket file descriptor in the first argument. The second is the request: SIOCGIFHWADDR &#8211; Catch the Hardware address. The next argument that it takes is a pointer to ifreq (but since ioctl takes only character arguments, it must be cast). Note that ifr.ifr_name should be filled with the correct device name (no extra spaces, not deleted 0s or anything&#8230; it should match ditto ditto. If not, check libnet_ifaddrlist program last time&#8217;s blog). If the device is filled, and valid, and if you have proper priviledges (perhaps) then this ioctl call neednt fail. But if it does, libnet does the error checking. If all went correctly, the hard ware address should be stored in the ifr_hwaddr sockaddr struct&#8217;s sa_data .<br />
What confused me earlier was the format in which it would be returned. It turns out that there is no formatting, the raw mac address is passed (yup, 1-&gt;1 bits). So, sa_data should be filled only with 6 bytes of data, cause mac addresses are 6 bytes.</p>
<p><code><br />
memcpy(eap, &amp;ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN);<br />
close(fd);<br />
return (eap);<br />
}<br />
</code><br />
This is the last part, quite simple. It does a 1 to 1 memory copy from ifr_hwaddr. Remember that ethernet (mac) addresses are 6 bytes, so you will have to say 6 as last parameter (ETHER_ADDR_LEN is a macro of libnet). The first arg is a pointer to the object of ether_addr , &amp;ea. The second is the actual data, which was retrieved from ioctl.</p>
<p>Well, thats it, we discussed how to get the mac address.</p>
<p><em>Usage</em><br />
Yeah, this is how you could use what you learnt to learn about a device&#8217;s mac address.<br />
<code><br />
#include "libnethead.h"<br />
int main(){<br />
//Let us get the ethernet hw address from the supplied device name.<br />
int fd,i;<br />
struct ether_addr ea;<br />
struct ifreq ifr;<br />
char buf[3];<br />
printf("Enter the device name: ");<br />
scanf("%s",ifr.ifr_name);<br />
//lets init a nice socket<br />
fd=socket(AF_INET,SOCK_DGRAM,0);<br />
if(ioctl(fd,SIOCGIFHWADDR,(char*)&amp;ifr)&lt;0){ close(fd); printf("Error\n"); exit(0); }<br />
memcpy(&amp;ea,&amp;ifr.ifr_hwaddr.sa_data,6);  //Ethernet address is 6<br />
for(i=0;i&lt;6;i++){<br />
sprintf(buf,"%x",ea.ether_addr_octet[i]);<br />
if(strlen(buf)&lt;2){ printf("0"); } //If there is preceeding 0, print it out<br />
printf("%s",buf);<br />
if(i!=5) printf(":");  //The colon in between the output.<br />
}<br />
printf("\b\n");<br />
return 0;<br />
}<br />
</code><br />
As usual, we use the header we made last time, libnethead.h . As you see, most part of the code was just initialising, getting input, and then correctly formatting and stupid stuff like that&#8230; Nothing real meaty (slurp)!<br />
Oh, btw, forgot to mention, that although I used memcpy to ea, you couldve done it better, just memcpy to a char hwaddr[IFNAMSIZ]; . I just wanted to show u the concepts used in the libnet script. Eventually, ether_addr_octet is just a character string itself.</p>
<p><em>Whats next:</em><br />
Good question. There are a few functions resembling getting the ethernet hwaddr, so I think I&#8217;ll just skim through some of them, in the next blog. That will be up soon. Probably the next (true) 1 will be totally different from what we did till now. Next time, we will create a function to make a nice little (empty) ethernet packet. I was in conflict to show how to open a socket for reading and writing to the line, but decided against it, since it would be no use if we don&#8217;t know what to send, right?</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/crackintheriver.wordpress.com/7/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/crackintheriver.wordpress.com/7/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/crackintheriver.wordpress.com/7/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/crackintheriver.wordpress.com/7/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/crackintheriver.wordpress.com/7/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/crackintheriver.wordpress.com/7/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/crackintheriver.wordpress.com/7/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/crackintheriver.wordpress.com/7/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/crackintheriver.wordpress.com/7/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/crackintheriver.wordpress.com/7/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/crackintheriver.wordpress.com/7/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/crackintheriver.wordpress.com/7/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=crackintheriver.wordpress.com&blog=1341848&post=7&subd=crackintheriver&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://crackintheriver.wordpress.com/2007/07/14/getting-mac-address-get_hwaddr/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/19318262334355190171496b623c1704?s=96&#38;d=identicon" medium="image">
			<media:title type="html">silverlightning</media:title>
		</media:content>
	</item>
		<item>
		<title>Getting Interface Lists- ifaddrlist</title>
		<link>http://crackintheriver.wordpress.com/2007/07/10/6/</link>
		<comments>http://crackintheriver.wordpress.com/2007/07/10/6/#comments</comments>
		<pubDate>Tue, 10 Jul 2007 17:52:53 +0000</pubDate>
		<dc:creator>Silver</dc:creator>
				<category><![CDATA[Libnet De-assembled]]></category>

		<guid isPermaLink="false">http://crackintheriver.wordpress.com/2007/07/10/6/</guid>
		<description><![CDATA[Hey *myself*,
I slept at 7 am today, and woke up at 4 pm. really long, and wanted to get up by 12 actually. Oh well, things don&#8217;t always work out the way we planned. Kinda like my internet as well. It aint working. I&#8217;m writing this on wordpad (I don&#8217;t like microsoft office for these [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=crackintheriver.wordpress.com&blog=1341848&post=6&subd=crackintheriver&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Hey *myself*,<br />
I slept at 7 am today, and woke up at 4 pm. really long, and wanted to get up by 12 actually. Oh well, things don&#8217;t always work out the way we planned. Kinda like my internet as well. It aint working. I&#8217;m writing this on wordpad (I don&#8217;t like microsoft office for these things).<br />
Today, I thought we could discuss about libnet_ifaddrlist today. But that requires some real hardware structuring using linux. It requires quite some background. While I ain&#8217;t going to provide a complete i/o communications manual, I&#8217;ll try to explain you what happens in some things-</p>
<p><em>Introduction to the pre-requisites-</em><br />
Approach: We can&#8217;t directly pinpoint the hardware, right? Unless we somehow could, we don&#8217;t (I dunno how to anyways). So, here&#8217;s what we do: The socket function sets up a connection using underlying devices, for a nice little connection. This connection has different parameters. We hence, back-track: getting the socket, then reading its attributes to get the lower level devices.<br />
socket() function: It accepts 3 arguments: The first is the family. Its usually set to AF_INET for internet sockets (which we use for even ethernet networks) although there are abt 10 other standards as well. The 2nd is the type of connection: Using streams or datagrams. The 3rd is the type: We use IPPROTO_RAW (0) for setting a raw IP packet (note: IP headers already included, TCP headers arent). Others are IPPROTO_TCP and IPPROTO_UDP.<br />
The most important thing about this however, is that it returns a file descriptor to the connection. This file is a special file (since its a network connection).<br />
ioctl() function: The ioctl function manipulates or reports the underlying device parameters of special files. For our purpose, we have the protocol (its actually variable argumnets in general tho): int ioctl(int [FILE DESCRIPTOR],int [REQUEST],[SOME WAY TO GET BACK or PROVIDE INFORMATION]); The last parameter depends on the [REQUEST].<br />
To get a nice little list of all possible [REQUEST] (for network interfaces), read: /include/bits/ioctls.h . I&#8217;ll describe only what we will use now though (since thats what I know)-<br />
SIOCGIFADDR: This gets the network interface list.  It accepts an argument of struct ifconf (described later). the ifc_len of the ifconf structure object should be set to the maximum size of the return. If its 0, then when ioctl is called, ifc_len would contain the length. That could be used to set an appropriate buffer. If its not 0, then the ifc_buf (and ifcu_req array, since they are part of union) is filled with the interface list: It is an array of ifreq structures, cast into a character array (or ifcu_req, in which case, its not cast <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' />  ).<br />
SIOCHIFFLAGS: Used to get the flags, or, the status of the device. It returns the short int ifr_flags. It accepts a ifreq structure pointer (yes, not ifconf), and returns the result in it. Note that the ifreq structure passed SHOULD contain the name of the device to be queried for. It could be written over, so its better to copy the device name, and especially the other parameters (like the address) before the ioctl call.<br />
SIOCGIFADDR: Used to get the &#8220;PA&#8221; address. Not sure whats PA address, probably the logical IP address. It gets the result in the ifr_addr sockaddr. It accepts a ifreq structure pointer (yes, not ifconf), and returns the result in it. Note that the ifreq structure passed SHOULD contain the name of the device to be queried for. It could be written over, so its better to copy the device name, and especially the other parameters (like the address) before the ioctl call.</p>
<p>IFF_ flags: Don&#8217;t ask me what they are called, I think they are called if flags as well. See, ifreq structure contains an int for flags. These flags are used to test that integer (and hence the device status). IFF flags are employed by using the AND bitwise (if that bit in integer is set) and concatenated with OR (if multiple bits are set.). You might guess that flags probably contain only 1 true bit, and the location of that 1, determines the flag. Thats my guess. For a list of flags, see /linux/if.h (which I found after quite some searching)<br />
About SA_LEN: Some o/s&#8217; , I think openBSD old versions are 1 of them, include a sa_len parameter in sockaddr definition. My version of OpenSuSE doesnt, but this is a short explaination to what I understood- Sometimes, on these systems, the sockaddr size could run OVER the expected size of sa_data (which is 14 bytes). In this case, the sa_len holds the length of the sockaddr array. However, if sa_len is smaller than sizeof(sockaddr), then nothing happens, cause sizeof(sockaddr) is like a minimum size of sockaddr. sa_len is kinda like the size, if sa_len &gt; sizeof(sockaddr). Atleast, thats what I understood. Perhaps, to keep this code compatibility, the ifc_buf is used, instead of directly reading the req.</p>
<p><em>Pre-requisite&#8217;ed code</em>-<br />
The following is some code which I consider reading pre-requisite, before jumping into the function.<br />
1. structure libnet_ifaddrlist<br />
<code>struct libnet_ifaddr_list<br />
{<br />
u_long addr;  //The address of device (probably not physical, may be logical. Physical would need 6 bytes)<br />
char *device;  //The device name, which is usually referenced.<br />
};</code><br />
Defined in libnet directory-&gt;includes/libnet/libnet-structures.h</p>
<p>2. structure ifreq (careful, big)-<br />
<code>struct ifreq{<br />
#define IFHWADDRLEN 6<br />
//hwaddrlen must probably be the number of bytes for MAC address. 6 bytes is the no. of<br />
//bytes taken by ethernet mac address.<br />
#define IFNAMESIZ IF_NAMESIZE<br />
union{<br />
char ifrn_name[IFNAMESIZ];<br />
} ifr_ifrn;<br />
union{<br />
struct sockaddr ifru_addr;<br />
struct sockaddr ifru_dstaddr<br />
struct sockaddr ifru_broadaddr<br />
struct sockaddr ifru_netmask;<br />
struct sockaddr ifru_hwaddr;<br />
short int ifru_flags;<br />
int ifru_ivalue;<br />
int ifru_mtu;<br />
struct ifmap ifru_map;<br />
char ifru_slave[IFNAMSIZ];<br />
char ifru_newname[IFNAMESIZ];<br />
__caddr_t ifru_data<br />
} ifr_ifru<br />
};<br />
#define ifr_name ifr_ifrn.ifrn_name /*Interface name (device name)*/<br />
#define ifr_hwaddr ifr_ifru_hwaddr /*Mac address*/<br />
#define ifr_addr   ifr_ifru.ifru_addr     /*address??? , perhaps the higher address. */<br />
#define ifr_dstaddr ifr_ifru.ifru_dstaddr   /*Other end of the p-p link (would be null, in out case, right?)*/<br />
#define ifr_broadaddr ifr_ifru.ifru_broadaddr  /* broadcast address */<br />
#define ifr_netmask ifr_ifru.ifru_netmask  /*Interface net mask*/<br />
#define ifr_flags  ifr_ifru_flags     /*Flags*/</code><br />
&#8230; Some other stuff. not important in our current discussion atleast.<br />
The ifreq structure is defined in /net/if.h as well as /linux/if.h , altho in /linux/ there is an additional param in ifr_ifru union: if_settings structure object ifru_settings . The ifreq is used to get the information of a particular interface.</p>
<p>3. definition of structure ifconf<br />
<code>struct ifconf{<br />
int ifc_len;<br />
union{<br />
char __user *ifcu_buf<br />
struct ifreq __user *ifcu_req;<br />
} ifc_ifcu;<br />
};<br />
#define ifc_buf ifc_ifcu.ifcu_buf   /*Buffer address*/<br />
#define ifc_req ifc_ifcu.ifcu_req   /*array of structures*/<br />
</code>This structure is defined in /linux/if.h (yup, da same). The ifconf is used to get the interface list.</p>
<p>4. IFF flags: God damn difficult to trace where they were. But anyways, here is a list (of commonly used ones).  (I&#8217;ve described using them earlier)-<br />
IFF_UP &#8211; If the interface is up<br />
IFF_LOOPBACK &#8211; If the interface is a loopback net<br />
IFF_POINTOPOINT &#8211; If device has point-point link. Probably used when the device is already on a virtual circuit/streaming a connection<br />
IFF_RUNNING &#8211; The device works, as in, it can successfully send and recieve packets.</p>
<p><strong>Code Dissection</strong>:<br />
Read the original code of libnet_ifaddrlist from libnet_if_addr list found in libnet directory-&gt;/src/ subdirectory. I&#8217;ll explain the function part by part. Keep up (btw, this function is skipped during compilation on solaris, since there, the default network device is le0. Its valid only for BSD and linux)-<br />
<code>int<br />
libnet_ifaddrlist(register struct libnet_ifaddr_list **ipaddrp,<br />
register char *errbuf)<br />
{<br />
</code>The definition: The function takes the libnet_ifaddr_list array pointer, and modifies it with the return. errbuf char string is used in case of erros. It returns the number of network interfaces found.</p>
<p><code>register int fd, nipaddr;<br />
#ifdef HAVE_SOCKADDR_SA_LEN<br />
register int n;<br />
#endif<br />
register struct ifreq *ifrp, *ifend, *ifnext, *mp;<br />
register struct sockaddr_in *sin;<br />
register struct libnet_ifaddr_list *al;<br />
</code><br />
struct ifconf ifc;<br />
struct ifreq ibuf[MAX_IPADDR], ifr;<br />
char device[sizeof(ifr.ifr_name) + 1];<br />
static struct libnet_ifaddr_list ifaddrlist[MAX_IPADDR];<br />
The fd is file descriptor for return value of socket(). nipaddr is to store number of interfaces found. ifrp, ifend,ifnext are used for traversing the interface list. ifrp is the current interface in question, ifrp is next stores the next address for the loop, and ifend is the end of the array. mp, well, I dont know why its there, cause I don&#8217;t find it used anywhere. The sockaddr_in *sin is that internet socket structure used for getting the logical address of device (the IP address as opposed to the raw logical address). The al is where all the interfaces will be sorted into at the end. The argument **ipaddrp is actually like a dummy. ipaddrp (the double pointer) is assigned to *al (array) (which coincidently also holds ifaddrlist).  The ifc structure is used to get the interface listing (raw listing) and is passed via the ioctl. The ibuf is kinda like an alias to the buffer @ ifc. The device character string is used to store the logical device name. ifaddrlist, as mentioned, is used in conjunction to al, cause ifaddrlist is @ the beginning of the array, al keeps traversing the array (I know nothing made sense now, but reading this description over again later on will help). MAX_IPADDR is prob some macro for some arbit max size (didnt bother finding out where)</p>
<p><code>fd = socket(AF_INET, SOCK_DGRAM, 0);<br />
if (fd &lt; 0)<br />
{<br />
sprintf(errbuf, "socket: %s", strerror(errno));<br />
return (-1);<br />
}<br />
ifc.ifc_len = sizeof(ibuf);<br />
ifc.ifc_buf = (caddr_t)ibuf;</code><br />
The first line, gets the file descriptor. A simple socket() function performs a great deal, including setting up a nice little connection point, and a file descriptor to it. The next few lines are error check if socket couldnt be initialised. ifc.ifc_len is set to the maximum length of the interface listing that should be returned. Thats required as a part of the SIOCGIFCONF request. The last line, well, it sets the ifc_buf pointer to the same memory as ibuf. So ibuf could access the same memory location as that buffer returned from ioctl call. Kinda like an alias.<br />
<code><br />
if (ioctl(fd,SIOCGIFCONF,(char *)&amp;ifc) &lt; 0 || ifc.ifc_len &lt; sizeof(struct ifreq))<br />
{<br />
sprintf(errbuf, "SIOCGIFCONF: %s", strerror(errno));<br />
close(fd);<br />
return (-1);<br />
}<br />
ifrp = ibuf;<br />
ifend = (struct ifreq *)((char *)ibuf + ifc.ifc_len);</code><br />
ioctl function call is used to get the devices acting below the special file descriptor. The fd is the FD passed to the ioctl function. The fd is over the network device, and hence becomes ideal for this. SIOCGIFCONF is used to get the list of interfaces. It takes a pointer to the ifconf object. In our case, thats ifc. If ioctl turns out 0 (or not -1), then success. If it returns -1, then you got problems. Maybe the method is not supported on that hardware, or something. The ioctl hence, comes in the if statement. The other part, it part after or, is confirmation that what is returned is atleast not junk. If ifc_len is less than even 1 ifreq structure, that means 1/2 a device is returned? lol, ofcourse not, its prob junk. So again, some error happened.<br />
Now the next part (after if error checking)- ifrp is the current ifreq structure under interrogation, which is set to the beginning of the list. (remember, ibuf and ifc.ifc_buf refer to the same location, but call it by different types: 1 by char, other by ifreq struct, wherein the ifreq struct is the right interpretation). The ifend refers to the memory location immediately AFTER the interfaces list. ifc_len is the length of bytes of list, and ibuf is the start. Ofcourse, what could be easier could be-: ifend=ibuf+(ifc.ifc_len)/sizeof(struct ifreq); or ifend=(struct ifreq*)(ifc.ifc_buf+ifc.ifc_len);</p>
<p><code>al = ifaddrlist;<br />
mp = NULL;<br />
nipaddr = 0;</code><br />
Just initialising. al is set to the beginning of ifaddrlist array (dunno why u need a pointer for tranversing the array, when we could use the index, but hell). mp, god knows why its there. nipaddr is the number of interfaces.</p>
<p><code>for (; ifrp &lt; ifend; ifrp = ifnext)<br />
{<br />
#ifdef HAVE_SOCKADDR_SA_LEN<br />
n = ifrp-&gt;ifr_addr.sa_len + sizeof(ifrp-&gt;ifr_name);<br />
if (n &lt; sizeof(*ifrp))<br />
{<br />
ifnext = ifrp + 1;<br />
}<br />
else<br />
{<br />
ifnext = (struct ifreq *)((char *)ifrp + n);<br />
}<br />
if (ifrp-&gt;ifr_addr.sa_family != AF_INET) continue;</code><br />
Here, the loop starts for traversing each address. ifrp already refers to the beginning. ifnext is known in the loop, and ifrp is set to it, kinda like an increment. So, this just goes through each of the network interfaces.<br />
The rest of it is if sa_len member is present in the sockaddr structure, which normally isnt (isnt for me). Skip. The n will get the the number of bytes supposed to be the sizeof the memory of the interface. Since ifr_addr is part of the union, and is the biggest of the structures (sockaddr). There are only 2 memory location units in ifreq: The union (whose max size is sizeof sockaddr) and the name buffer. Both are accounted for. But the sa_len extends the memory of the sockaddr. If sa_len&gt;sizeof(sockaddr), then ifnext would be set to the next valid location, which goes over the expected size. Else, ifnext is set to the next immediate location.</p>
<p><code>#else<br />
ifnext = ifrp + 1;<br />
#endif</code><br />
dude, you must know this. Its the regular increment <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' />  . Thats what normally happens. Infact, if sa_len was not declared, the loop would be easier, much easier.<br />
<code><br />
/*<br />
* Need a template to preserve address info that is<br />
* used below to locate the next entry.  (Otherwise,<br />
* SIOCGIFFLAGS stomps over it because the requests<br />
* are returned in a union.)<br />
*/<br />
strncpy(ifr.ifr_name, ifrp-&gt;ifr_name, sizeof(ifr.ifr_name));<br />
if (ioctl(fd, SIOCGIFFLAGS, (char *)&amp;ifr) &lt; 0)<br />
{<br />
if (errno == ENXIO) continue;<br />
sprintf(errbuf,<br />
"SIOCGIFFLAGS: %.*s: %s",<br />
(int)sizeof(ifr.ifr_name),<br />
ifr.ifr_name,<br />
strerror(errno));<br />
close(fd);<br />
return (-1);<br />
}</code><br />
Read the comment if u want. I didnt understand a shit out of it. The strncpy, um&#8230;. strange as it is, cause ifr and ifrp are part of the same ifreq struct, and its like copying the entire string. Nyways, strncpy is always a better practice (buffer overflow prevention). As for why the copying, perhaps to prevent the ifr_name from getting overwritten. ioctl could become notorious for losing data. It takes in data and outputs it in the same argument. So its always better to copy all the stuff iin ifreq before passing it to ioctl. (or in this case, just copy the device name to another struct instead of passing the original)<br />
The next call is to get the status of the particular device. For that, again ioctl, but this time, with the SIOCGIFFLAGS request, and the corresponding ifr pointer. If its not successful, an error message is set, using global errno (as in normal socket operations). If errno== ENXIO , which means, that the device is offline/inaccessible, then its ok to continue the loop, cause multiple devices may be offline. But if its some other error, then it must be reported and function failed (like, microprocessor starts acting funny by passing interrupt to keyboard or sumthing instead <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' />  )</p>
<p><code>/* Must be up and not the loopback */<br />
if ((ifr.ifr_flags &amp; IFF_UP) == 0 || LIBNET_ISLOOPBACK(&amp;ifr))<br />
{<br />
continue;<br />
}</code><br />
This checks up the correct flags to make sure that the device is valid. Though online, the device might not be up. This is possible if the device is powered and connected to comp, but not to the network. The first part of the if expression checks if the device is up (common sense tells us how flags work, esp. bit flags. So, if they return 0, the flag was not set, and hence, comparison failed). The second is actually a macro, in -&gt;/include/libnet/libnet-macro.h .<br />
The first expression checks if device is NOT up. The second checks if device IS loopback. LIBNET_ISLOOKBACK is equivalent to: (ifr.ifr_flags &amp; IFF_LOOPBACK) != 0 . If the device is not up or loopback proceed with next device, with next iteration.</p>
<p><code>strncpy(device, ifr.ifr_name, sizeof(ifr.ifr_name));<br />
device[sizeof(device) - 1] = '';<br />
if (ioctl(fd, SIOCGIFADDR, (char *)&amp;ifr) &lt; 0)<br />
{<br />
sprintf(errbuf, "SIOCGIFADDR: %s: %s", device, strerror(errno));<br />
close(fd);<br />
return (-1);<br />
}</code><br />
This resembles the earlier ioctl call alot. The last 1 got the flags, this 1 gets the the address <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  . This 1 calls up the SIOCCGIFADDR request with ioctl. But first, just saves the device name before the ioctl call, in device string (lol, atlast, a normal character string). Then, we query ioctl, and do the bogus error checking the same way. Now, the ifr.ifr_addr is filled with the &#8220;PA&#8221; address of the device, probably the joint IP address+port+family or sumthing. Casting it to sockaddr_in , we should be able to get the ip address!</p>
<p><code>sin = (struct sockaddr_in *)&amp;ifr.ifr_addr;<br />
al-&gt;addr = sin-&gt;sin_addr.s_addr;<br />
/*<br />
*  Replaced savestr() with strdup().  -- MDS<br />
*/<br />
al-&gt;device = strdup(device);<br />
++al;<br />
++nipaddr;<br />
}<br />
close(fd);</code><br />
And as I said earlier, it was cast to sockaddr_in for internet sockets. sin_addr is a part of in_addr, which is a structure containing only 1 element: s_addr, which is a 32 bit int (4 bytes) ) (numeric ip address. To get the presentation Ip address, use inet_ntop(AF_INET,&amp;(sin-&gt;sin_addr.s_addr),dest,sizeof(dest)) where dest is a character string of 12+1 characters.<br />
Then the rest is simple. Just add that device to the ifaddrlist array (through the al pointer). (strdup just copies the string and returns a pointer to the copied) Also, update the number of records, by nipaddr increment.<br />
<code><br />
*ipaddrp = ifaddrlist;<br />
return (nipaddr);<br />
}<br />
#endif  /* !__solaris__ */</code><br />
That just repoints the passed argument to the interface list, which now contains a nice little list of device name and associated ip address. Also, return the number of records, from nipaddr. Finally, endif the solaris, cause this full function shouldnt be compiled under solaris.</p>
<p><strong>Usage</strong>:<br />
Lets use this function we learnt to output the interface device names.<br />
<code>#include "libnethead.h"<br />
#define MAX_IPADDR 15<br />
//Let the max number of interfaces be 15. Put something arbit big.<br />
struct libnet_ifaddr_list{<br />
long addr;<br />
char *device;<br />
};<br />
int main(){<br />
struct libnet_ifaddr_list *address_list;<br />
char errbuf[100];<br />
int i;<br />
int no;<br />
no=libnet_ifaddrlist(&amp;address_list,errbuf);<br />
if(no==-1){ printf("Error: %s",errbuf); exit(1); }<br />
for(i=0;i&lt;no;i++){<br />
printf("Device: %s ,\t Address: %d\n",(address_list[i]).device,(address_list[i]).addr);<br />
}<br />
return 0;<br />
}<br />
//Below is more or less copy-paste, with a bit of editing to make it independent of libnet constants<br />
int libnet_ifaddrlist(register struct libnet_ifaddr_list **ipaddrp,register char *errbuf){<br />
register int fd, nipaddr;<br />
register struct ifreq *ifrp, *ifend, *ifnext, *mp;<br />
register struct sockaddr_in *sin;<br />
register struct libnet_ifaddr_list *al;<br />
struct ifconf ifc;<br />
struct ifreq ibuf[MAX_IPADDR], ifr;<br />
char device[sizeof(ifr.ifr_name) + 1];<br />
static struct libnet_ifaddr_list ifaddrlist[MAX_IPADDR];<br />
fd = socket(AF_INET, SOCK_DGRAM, 0);<br />
if (fd &lt; 0)<br />
{<br />
sprintf(errbuf, "socket: %s", strerror(errno));<br />
return (-1);<br />
}<br />
ifc.ifc_len = sizeof(ibuf);<br />
ifc.ifc_buf = (caddr_t)ibuf;<br />
if (ioctl(fd,<br />
SIOCGIFCONF,<br />
(char *)&amp;ifc) &lt; 0 || ifc.ifc_len &lt; sizeof(struct ifreq))<br />
{<br />
sprintf(errbuf, "SIOCGIFCONF: %s", strerror(errno));<br />
close(fd);<br />
return (-1);<br />
}<br />
ifrp = ibuf;<br />
ifend = (struct ifreq *)((char *)ibuf + ifc.ifc_len);<br />
al = ifaddrlist;<br />
mp = NULL;<br />
nipaddr = 0;<br />
for (; ifrp &lt; ifend; ifrp = ifnext)<br />
{<br />
ifnext = ifrp + 1;<br />
strncpy(ifr.ifr_name, ifrp-&gt;ifr_name, sizeof(ifr.ifr_name));<br />
if (ioctl(fd, SIOCGIFFLAGS, (char *)&amp;ifr) &lt; 0)<br />
{<br />
if (errno == ENXIO) continue;<br />
sprintf(errbuf,<br />
"SIOCGIFFLAGS: %.*s: %s",<br />
(int)sizeof(ifr.ifr_name),<br />
ifr.ifr_name,<br />
strerror(errno));<br />
close(fd);<br />
return (-1);<br />
}<br />
/* Must be up and not the loopback */<br />
if (((ifr.ifr_flags &amp; IFF_UP) == 0) || ((ifr.ifr_flags &amp; IFF_LOOPBACK)==1))<br />
{<br />
continue;<br />
}<br />
strncpy(device, ifr.ifr_name, sizeof(ifr.ifr_name));<br />
device[sizeof(device) - 1] = '';<br />
if (ioctl(fd, SIOCGIFADDR, (char *)&amp;ifr) &lt; 0)<br />
{<br />
sprintf(errbuf, "SIOCGIFADDR: %s: %s", device, strerror(errno));<br />
close(fd);<br />
return (-1);<br />
}<br />
sin = (struct sockaddr_in *)&amp;ifr.ifr_addr;<br />
al-&gt;addr = sin-&gt;sin_addr.s_addr;<br />
al-&gt;device = strdup(device);<br />
++al;<br />
++nipaddr;<br />
}<br />
close(fd);<br />
*ipaddrp = ifaddrlist;<br />
return (nipaddr);<br />
}<br />
//EOF//<br />
</code>You would ofcourse need the file libnethead.h . Dont worry, it aint something mysterious, its just a holy bunch of includes we have. I know that most of them arent necessary for this program, but having a common template helps (also, I didnt bother figuring out which were needed, which werent <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' />  ). Here is libnethead.h (just put it in the same directory as the file above).<br />
<code><br />
#include &lt;stdio.h&gt;<br />
#include &lt;string.h&gt;<br />
#include &lt;unistd.h&gt;<br />
#include &lt;fcntl.h&gt;<br />
#include &lt;signal.h&gt;<br />
#include &lt;stdlib.h&gt;<br />
#include &lt;sys/ioctl.h&gt;<br />
#include &lt;sys/stat.h&gt;<br />
#include &lt;sys/types.h&gt;<br />
#include &lt;ctype.h&gt;<br />
#include &lt;sys/socket.h&gt;<br />
#include &lt;netinet/in.h&gt;<br />
#include &lt;netinet/in_systm.h&gt;<br />
#include &lt;netinet/ip.h&gt;<br />
#include &lt;net/if.h&gt;<br />
#include &lt;net/ethernet.h&gt;<br />
#include &lt;netinet/tcp.h&gt;<br />
#include &lt;netinet/udp.h&gt;<br />
#include &lt;linux/igmp.h&gt;<br />
#include &lt;arpa/inet.h&gt;<br />
#include &lt;sys/time.h&gt;<br />
#include &lt;netdb.h&gt;<br />
#include &lt;errno.h&gt;<br />
#include &lt;stdarg.h&gt;<br />
</code><br />
Note that no additional stuff is required, other than this. Also, note that this file is not universal. It works with my build of OpenSuSE 10.2, on a IA32 platform. It may be a bit different on others. Modify/clip ur version of libnet.h (in libnet folder) to suite ur suite.<br />
Compile the code, and voila! If you get nothing, don&#8217;t worry, you prob dont have any up (or nonloopback) network devices connected to ur computer at the moment. To check for loopback devices as well, remove that IFF_LOOPBACK thing.</p>
<p>Congratulations: You&#8217;ve communicated with &#8220;super&#8221; low level network jumble and got what you needed! Take a break. I know I need 1 <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' />  .</p>
<p><em>Whats Next</em>:<br />
Perhaps a movie (:D) . Seriously, if your anything like me, u&#8217;d wanna watch 1 now, cause this stuff was heavy but damn important. I&#8217;m glad its out of the way, because these sort of things are perhaps the most undocumented things available. Once we are able to setup and transmit a ethernet line, we&#8217;re made, cause then is left all that packet creation crap, stuff for which the rfc&#8217;s are golden source&#8217;s of info.<br />
As for whats next on the blog (whenever I post this, after that): Probably the function: libnet_get_hwaddr for getting the ethernet address (MAC address) . I expect it to be real small though, resembling ioctl to get the device hwaddr in that ifreq structure. What will be interesting is actually getting that and parsing it to make it human readable.</p>
<p>Update on internet (rofl, personal): Well, talked to you telecom ppl. Shitty stuff, they blocked the internet for sum ugly overusgae or sumthing. No warning, and way before due date. I couldnt hear them properly on phone, so heck, didnt bother listening to pukeface talking on the other end of the line anyways. Lets see, I&#8217;ll try to upload this asap, perhaps from my fathers&#8217; reliance connection.<br />
Update: Well, its almost perfectly 24 hours since I wrote this article, and now I get internet and time to post it. Next is getting the interface&#8217;s mac address, damm simple.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/crackintheriver.wordpress.com/6/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/crackintheriver.wordpress.com/6/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/crackintheriver.wordpress.com/6/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/crackintheriver.wordpress.com/6/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/crackintheriver.wordpress.com/6/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/crackintheriver.wordpress.com/6/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/crackintheriver.wordpress.com/6/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/crackintheriver.wordpress.com/6/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/crackintheriver.wordpress.com/6/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/crackintheriver.wordpress.com/6/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/crackintheriver.wordpress.com/6/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/crackintheriver.wordpress.com/6/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=crackintheriver.wordpress.com&blog=1341848&post=6&subd=crackintheriver&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://crackintheriver.wordpress.com/2007/07/10/6/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/19318262334355190171496b623c1704?s=96&#38;d=identicon" medium="image">
			<media:title type="html">silverlightning</media:title>
		</media:content>
	</item>
		<item>
		<title>Starting ethernet communication: select_device</title>
		<link>http://crackintheriver.wordpress.com/2007/07/09/starting-ethernet-communication-select_device/</link>
		<comments>http://crackintheriver.wordpress.com/2007/07/09/starting-ethernet-communication-select_device/#comments</comments>
		<pubDate>Mon, 09 Jul 2007 00:37:18 +0000</pubDate>
		<dc:creator>Silver</dc:creator>
				<category><![CDATA[Libnet De-assembled]]></category>

		<guid isPermaLink="false">http://crackintheriver.wordpress.com/2007/07/09/starting-ethernet-communication-select_device/</guid>
		<description><![CDATA[Firstly, have a look at the IP stack @ http://en.wikipedia.org/wiki/Internet_protocol_suite . It explains stuff. Though its wikipedia, its quite detailed and technical, which is brilliant. I am really bothered abt the figure, btw, that 5 layer table.
&#160;
Anyways, lets explore libnet. We see a doc folder. Go, and see the HTML documents, serial order ofcourse. You&#8217;d [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=crackintheriver.wordpress.com&blog=1341848&post=5&subd=crackintheriver&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p align="left">Firstly, have a look at the IP stack @ http://en.wikipedia.org/wiki/Internet_protocol_suite . It explains stuff. Though its wikipedia, its quite detailed and technical, which is brilliant. I am really bothered abt the figure, btw, that 5 layer table.</p>
<p align="left">&nbsp;</p>
<p align="left">Anyways, lets explore libnet. We see a doc folder. Go, and see the HTML documents, serial order ofcourse. You&#8217;d understand the first 3-4 pages. If you don&#8217;t, fuck off- either u aint concentrating, or you don&#8217;t know enough. If its the first, good, thats what happened to me the first time. But if its 2nd, you need to wait for another 1/2 year to get and read material pre-requisite to this blog.</p>
<p align="left">&nbsp;</p>
<p align="left">Now, in your opera/firefox , open 2 tabs, 1 having 5.html and other 6.html . These are by far the 2 most important documents you&#8217;d need to be open.</p>
<p align="left">&nbsp;</p>
<p align="left">Since we&#8217;re dissecting the source, we wouldnt bother much with the memory management part of libnet, atleast as yet. We are more interested in the communication with the modem/router/card, and how to form and send packet headers (along with payload if any). I DONT know the entire process as yet, so I might make some mistakes here, and rectify/negate them later. Don&#8217;t scream @ me, I aint accountable to you, its my blog!</p>
<p align="left">&nbsp;</p>
<p align="left">Anyways, I assume that basic IP headers are easier to construct. So, lets start off with link layer instead, which is definately much more complex, but is found &#8220;NOWHERE&#8221; (no book, very very few source codes, no articles, hardly any papers, nothing abt link layer programming)</p>
<p align="left">&nbsp;</p>
<p align="left">So, we see that the basic way to start a link layer communication is by libnet_open_link_interface. Read 5.html. It takes 2 arguments. The first is important, its the device. The second is merely an error buffer for error message. From the practical point of view, we must first find out which device is to be used. We must use a non-loopback device, which is up (ie, working). To do this, lets use the libnet_select_device() function.</p>
<p align="left">&nbsp;</p>
<p align="left"><strong>libnet_select_device -<br />
</strong>It takes the form: int libnet_select_device(struct sockaddr_in *sin, u_char **device, u_char *ebuf); . Dont be perplexed. Breaking it down-<br />
sockaddr_in  is that SOCKADDR structure for the Internet suite. Its basically sockaddr but casted better, in more human readable form.<br />
**device : No sweat. Make a blank string. Pass the address of the string (ye, address of pointer of first character of string). I realise this is pretty retarded however, since you could modify the string without the pointer address.<br />
*ebuf: Just an empty string, which could have an error message if there is some error.<br />
On failure, the function returns -1. Else, contains true (1).</p>
<p align="left">&nbsp;</p>
<p align="left"><em>For example</em></p>
<p align="left">&nbsp;</p>
<p align="left"><code>.....<br />
char *device=NULL,*buf=NULL;<br />
struct sockaddr_in sin; //lame<br />
if(libnet_select_device(&amp;sin,&amp;device,buf)==-1){ printf("Your interface is down or sumthing: %s",buf); exit(1); }<br />
.... //Use device for the rest of the time.<br />
</code></p>
<p align="left">&nbsp;</p>
<p align="left">That was a for example. You could use the pcap interface (remember, libnet is useful for sending packets, but usually with libpcat for sniffing the net, libnet&#8217;s power increases manifolds), Cause thats whats done in dniff (which is a open source sniffer)</p>
<p align="left">&nbsp;</p>
<p align="left">(sideline note: Just running thru connecting with devices routines, ahem, very complex guys&#8230; all distinct and stuff)</p>
<p align="left">&nbsp;</p>
<p align="left">The libnet_select_device is present in /src/libnet_if_addr.c file. Opening that, here&#8217;s libnet_select_device function-<br />
<code>int<br />
libnet_select_device(struct sockaddr_in *sin, u_char **device, u_char *errbuf)<br />
{<br />
int c, i;<br />
char err_buf[BUFSIZ];<br />
struct libnet_ifaddr_list *address_list;<br />
#if (__solaris__)<br />
/*<br />
*  XXX - this is temporary and needs to be better documented.<br />
*/<br />
*device = "le0";<br />
return (1);<br />
#else<br />
/*<br />
*  Number of interfaces.<br />
*/<br />
c = libnet_ifaddrlist(&amp;address_list, err_buf);<br />
if (c &lt; 0)<br />
{<br />
sprintf(errbuf, "ifaddrlist : %s\n", err_buf);<br />
return (-1);<br />
}<br />
else if (c == 0)<br />
{<br />
sprintf(errbuf, "No network interfaces found.\n");<br />
return (-1);<br />
}<br />
if (*device)<br />
{<br />
for (i = c; i; --i, ++address_list)<br />
{<br />
if (!(strncmp(*device, address_list-&gt;device, strlen(address_list-&gt;device))))<br />
{<br />
break;<br />
}<br />
}<br />
if (i &lt;= 0)<br />
{<br />
sprintf(errbuf, "Can't find interface %s\n", *device);<br />
return (-1);<br />
}<br />
}<br />
sin-&gt;sin_family = AF_INET;<br />
sin-&gt;sin_addr.s_addr = address_list-&gt;addr;<br />
/*<br />
*  Do we need to assign a name to device?<br />
*/<br />
if (!*device)<br />
{<br />
if (c &gt; 1)<br />
{<br />
#if (__DEBUG)<br />
fprintf(stdout,<br />
"Multiple interfaces found, using %s @ %s.\n",<br />
host_lookup(sin-&gt;sin_addr.s_addr, 0),<br />
address_list-&gt;device);<br />
#endif<br />
}<br />
*device = address_list-&gt;device;<br />
}<br />
return (1);<br />
}<br />
#endif  /* __solaris__ */</code></p>
<p align="left">&nbsp;</p>
<p align="left">We see that script has support for solaris: A system we don&#8217;t bother exploring. But looks like the default active modem device is set by the handle le0 automatically. lol, solaris rox for this.<br />
But linux aint so lucky. First, it checks through  ifaddrlist  for some stuff&#8230;. Yeah, I&#8217;m looking at that function now&#8230; check it out, its right above select_device (I&#8217;d describe it in my next post perhaps. This 1 is for select_device)</p>
<p align="left">&nbsp;</p>
<p align="left">Deviation: Since this is taking longer then anticipated, here are links which I used to find out how stuff is done:<br />
http://docs.sun.com/app/docs/doc/802-1930-07/6i5u9741f?a=view &#8211; Cool link.<br />
http://ecos.sourceware.org/docs-latest/ref/openbsd-manpages-netintro.html &#8211; BSD reference for ifreq and ioctl<br />
http://www.delorie.com/gnu/docs/glibc/libc_305.html &#8211; If sa_len is not defined (if defined, then see first link)</p>
<p align="left">&nbsp;</p>
<p align="left">And done (phew), after abt 1/2-1 hour.  I&#8217;ll admit it, I never used ioctl ever  in my life before, and  finding out stuff about it is  hard.</p>
<p align="left">&nbsp;</p>
<p align="left">Anyways, back to the code. The libnet_ifaddrlist() takes a regular double pointer to libnet_ifaddr_list and in that pointer, returns a list of active interfaces (non-loopback). Each entry of the array returned contains a device name, and the mac address of the interface. It returns the number of interfaces.</p>
<p align="left">&nbsp;</p>
<p align="left">So, c is returned the number of interfaces (back in libnet_select_device btw). As you can see, it select device does some bogus checks at first. Then, it goes and checks if a particular device is working or not. This is simple to check really. Just go through the devices returned by libnet_ifaddrlist , and compare if any of the devices in that list match the device passed. This is, ofcourse, followed, only if device argument is not null (we normally use null right, to GET the device. But this function can also check the validity of a device).</p>
<p align="left">&nbsp;</p>
<p align="left">Then it merely copies the device(s), if multiple, then the first device in the array. This device is simply copied to the passed **device argument, and a nice &#8220;true&#8221; is returned.</p>
<p align="left">&nbsp;</p>
<p align="left"><em>Sorry:</em> Sorry to disappoint. I thought the function will be more involved, but turns out that the libnet_ifaddrlist is the beast, not select_device. I realised that WHEN I was writing this post.</p>
<p align="left">&nbsp;</p>
<p align="left"><em> Use:</em> Not much, I&#8217;ll give you that. The function itself is quite easy to understand if you know about libnet structures and stuff in general, and I&#8217;m happy it turned out to be the first I discussed, cause it was easy. However, I can&#8217;t help to say, it was more like a wrapper function+&#8221;little&#8221; functionality+error reporting . But this is a very useful function in general, for getting the most convenient interface. However, we havent discussed enough for a full fledged program to exploit this function.</p>
<p align="left">&nbsp;</p>
<p align="left"><em>Whats next:</em> Duh, next post, which will be prob after much much more extensive research (lol, most of it, done today, but I prefer real EXTENSIVE.) is about lib_ifaddrlist . Wish me luck about finding about Ifflags in linux.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/crackintheriver.wordpress.com/5/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/crackintheriver.wordpress.com/5/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/crackintheriver.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/crackintheriver.wordpress.com/5/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/crackintheriver.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/crackintheriver.wordpress.com/5/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/crackintheriver.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/crackintheriver.wordpress.com/5/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/crackintheriver.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/crackintheriver.wordpress.com/5/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/crackintheriver.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/crackintheriver.wordpress.com/5/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=crackintheriver.wordpress.com&blog=1341848&post=5&subd=crackintheriver&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://crackintheriver.wordpress.com/2007/07/09/starting-ethernet-communication-select_device/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/19318262334355190171496b623c1704?s=96&#38;d=identicon" medium="image">
			<media:title type="html">silverlightning</media:title>
		</media:content>
	</item>
		<item>
		<title>Why this blog?</title>
		<link>http://crackintheriver.wordpress.com/2007/07/08/why-this-blog/</link>
		<comments>http://crackintheriver.wordpress.com/2007/07/08/why-this-blog/#comments</comments>
		<pubDate>Sun, 08 Jul 2007 21:30:54 +0000</pubDate>
		<dc:creator>Silver</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://crackintheriver.wordpress.com/2007/07/08/why-this-blog/</guid>
		<description><![CDATA[The obvious question is why this blog? Well, this isn&#8217;t for you, its for me. In these holidays (which are coming to an end) I learnt, and am learning so much, but am also forgetting a lot. So, this blog is to help me remember. This will be a personal cum super technical blog, technical [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=crackintheriver.wordpress.com&blog=1341848&post=4&subd=crackintheriver&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>The obvious question is why this blog? Well, this isn&#8217;t for you, its for me. In these holidays (which are coming to an end) I learnt, and am learning so much, but am also forgetting a lot. So, this blog is to help me remember. This will be a personal cum super technical blog, technical being dealing with complex stuff, mainly networking related, especially networking in C.</p>
<p>Its a shame that soo.. so&#8230; few references are available for low level networking. Any1 who needs that interface really needs to work themselves from ground up, which is kinda sad, when you think about it. I had the same problem.But since yesterday, I worked myself up this ladder, and atlast, I am in a position where I have all I need to understand the topic.</p>
<p>This blog is mainly for posting daily notes about those topics. For people who understand what I am doing (alot of ethernet and IP protocol and packets programming), reading this blog, you will be grateful to me for making it. But I know no1 reads about this stuff. No1 bothers how stuff works below, as long as @ high level, stuff is as simple as a button click.</p>
<p>Here is the libnet library which is my main/ultimate reference. Unlike the libnet in linux, which is precompiled, this 1 is source, so you could actually explore it, and generate routines by yourself even without libnet. But a hearty thanx to the creator of libnet. And I&#8217;d be ever so in debt to him.</p>
<p>Here&#8217;s a copy of libnet source: http://rapidshare.com/files/41646085/libnet-1.0.1b.tar.gz.html</p>
<p>And so, the experiment starts.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/crackintheriver.wordpress.com/4/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/crackintheriver.wordpress.com/4/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/crackintheriver.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/crackintheriver.wordpress.com/4/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/crackintheriver.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/crackintheriver.wordpress.com/4/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/crackintheriver.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/crackintheriver.wordpress.com/4/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/crackintheriver.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/crackintheriver.wordpress.com/4/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/crackintheriver.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/crackintheriver.wordpress.com/4/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=crackintheriver.wordpress.com&blog=1341848&post=4&subd=crackintheriver&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://crackintheriver.wordpress.com/2007/07/08/why-this-blog/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/19318262334355190171496b623c1704?s=96&#38;d=identicon" medium="image">
			<media:title type="html">silverlightning</media:title>
		</media:content>
	</item>
		<item>
		<title>Orkut/google login schemas</title>
		<link>http://crackintheriver.wordpress.com/2007/07/08/orkutgoogle-login-schemas/</link>
		<comments>http://crackintheriver.wordpress.com/2007/07/08/orkutgoogle-login-schemas/#comments</comments>
		<pubDate>Sun, 08 Jul 2007 21:19:41 +0000</pubDate>
		<dc:creator>Silver</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://crackintheriver.wordpress.com/2007/07/08/orkutgoogle-login-schemas/</guid>
		<description><![CDATA[My original personal blog @ fh-net.com seems to be down cause fh-net.com is down. So here&#8217;s a copy of that post I made on orkut/google login schemas
&#160;
Firstly, only those with deep understanding of cookies and sessions and logins, please view this. This is totally original article, trying to figure out all about orkut. Its more [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=crackintheriver.wordpress.com&blog=1341848&post=3&subd=crackintheriver&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>My original personal blog @ fh-net.com seems to be down cause fh-net.com is down. So here&#8217;s a copy of that post I made on orkut/google login schemas</p>
<p class="ohtmlParent">&nbsp;</p>
<p class="ohtml">Firstly, only those with deep understanding of cookies and sessions and logins, please view this. This is totally original article, trying to figure out all about orkut. Its more like a “Hey, it happens this way” than “Whao, I found out sumthing amazing”<br />
Firstly, lets what happens when you visit orkut.com . You get to a screen which sets the tracker google analytic cookies and TZ cookie (both of which, we dont bother with). On the login page, is a iframe pointing to: https://www.google.com/accounts/ServiceLoginBox . It contains the (important) parameters-<br />
service=orkut<br />
skipll=true&amp;skipvpage=true<br />
continue=http%3A%2F%2Fwww.orkut.com%2FRedirLogin.aspx%3Fmsg%3D0%26page%3Dhttp%253A%252F%252Fwww.orkut.com%252F<br />
followup=http%3A%2F%2Fwww.orkut.com%2FGLogin.aspx<br />
hl=en-US (lang)<br />
Just decoding the continue string, we see-<br />
http://www.orkut.com/RedirLogin.aspx?msg=1&amp;page=http%3A%2F%2Fwww.orkut.com%2F<br />
Go there and try out. Looks like a normal login page, but the service box is redundant. You see, that now, the continue will be like-<br />
http://www.orkut.com/RedirLogin.aspx?msg=0&amp;page=http%3A%2F%2Fwww.orkut.com%2FRedirLogin.aspx%3Fmsg%3D1%26page%3Dhttp%253A%252F%252Fwww.orkut.com%252F%26followup%3Dhttp%3A%2F%2Fwww.orkut.com%2FGLogin.aspx<br />
Decoding the “page” variable-<br />
http://www.orkut.com/RedirLogin.aspx?msg=1&amp;page=http%3A%2F%2Fwww.orkut.com%2F&amp;followup=http://www.orkut.com/GLogin.aspx</p>
<p>Recognise it? It means that when we send the form to google for login, the referer page is also sent along with it. And note, that this is totally independent of whether u’ve logged in or not to orkut already (you will see where I am going with this later). Also, just note the address of the page. Its Glogin.aspx?done=[page] . Think!</p>
<p>Alright, thats preliminary check. Now lets see what gets sent when you submit the form (yeah, I’m lazy to read source)-<br />
continue=http%3A%2F%2Fwww.orkut.com%2FRedirLogin.aspx%3Fmsg%3D0%26page%3D%252FHome.aspx%253Fxid%253D5239296434780423392 &amp; followup=http%3A%2F%2Fwww.orkut.com%2FGLogin.aspx &amp; service=orkut &amp; nui=2 &amp; skipvpage=true &amp; skipll=true &amp; hl=en-US &amp; GA3T=CQ78r8M_LWU &amp; Email=[something] &amp; Passwd=[something] &amp; PersistentCookie=yes &amp; rmShown = 1 &amp; null=Sign+in</p>
<p>Most things we remember. The GA3T prob is Google Accounts **, not sure what, but there is a seemingly random value associated with it, probably some sortof checksum (perhaps google skips referer check for cross browser compatibility). Most other stuff is either due to browser settings, or that “remember me” option.</p>
<p>Posting this, we get a nice lil response from google, which firstly sets the following cookies-<br />
SID= Some TREMENDOUSLY LONG case-sensitive alphanumeric but having hyphens at regular intervals (prob consists of number of components concatenated) (expires sumwhere in 2017)<br />
GA3T=CQ78r8M_LWU (recognise this <img src="http://blog.legacy.fh-net.com/wp-includes/images/smilies/icon_smile.gif" alt=")" /> ) . It prob may be a checksum for making cookies a bit more secure or sumthing<br />
GoogleAccountsLocale_session= en (english)<br />
LSID= Now this one is strange. Viewing the headers, it shows some real crap. It sets this multiple times, but makes sure it expires in 1990. And eventually, it gets set to= DQAAAI****AIqgK9HyWnrp9wJnJnXKIkXu4CYxpgoloNv5i8I*zOaFD7oPenHC_yxaAXobufNmpYq113BsqoFfDJ7YiIgahYLm5F1*K4Dude2ms4rcNcNcDOzCyAYg9othn1Ii1yvrKkPGXAG9E2jBm8Um*U5towqpD1D10PCdizJvwU3LAg1Q , but via a secure connection. All I see is the word: Dude which makes sense <img src="http://blog.legacy.fh-net.com/wp-includes/images/smilies/icon_smile.gif" alt=")" /><br />
Then, it decently outputs sum javascript to redirect to TokenAuth</p>
<p>The TokenAuth<br />
The GET query_string is long, so I break it up as (and decode)-<br />
continue=https://www.google.com/accounts/CheckCookie?continue=http%3A%2F%2Fwww.orkut.com%2FRedirLogin.aspx%3Fmsg%3D0%26page%3D%252FHome.aspx%253Fxid%253D5239296434780423392&amp;followup=http%3A%2F%2Fwww.orkut.com%2FGLogin.aspx&amp;service=orkut&amp;hl=en-US&amp;chtml=LoginDoneHtml&amp;skipvpage=true<br />
auth=TREMEMDOUSLY long string again.</p>
<p>We are more interested in the outcome. The script AGAIN set the SID and LSID cookie to the values earlier (again, LSID has those bogus expires as well), with everything the same. It sends a 302 (relocated) message, and redirects to CheckCookie with the query string parameters-<br />
continue=http://www.orkut.com/RedirLogin.aspx?msg=0&amp;page=%2FHome.aspx%3Fxid%3D5239296434780423392<br />
followup=http://www.orkut.com/GLogin.aspx<br />
service=orkut<br />
hl=en-US<br />
chtml=LoginDoneHtml<br />
skipvpage=true (no clue abt this 1)</p>
<p>SO, we find that TokenAuth probably had no sense to be there in the first place. It places the same old cookies back with the same old values, and redirects to checkcookie, even without any other token.<br />
And voila, still nothing, yet another seemingly useless redirection, cause checkcookie, although might be “checking” the cookies, doesnt modify any values as such. The value of SID aint changed, and LSID is reset in the same lame manner as it is earlier. But look beyond and see that there is a redirection on this page, to SetSID , which accepts a long query-string.<br />
ssdc=1<br />
sidt=NCWYYhMBAAA=.D9uKQk+/7Um5yenrm0f6GQwd2bccekqTV744ZrWxuXzF4Y6KMUYk4Wj331p9BEuw4MHl5RR7CnPemACZoXdiG66p/2d8kehVu6rzsLoCSVmGV9/yMRZg7uJjJx/ib95mIGFZ4qsR0gecJMsjOBYlteWUrDJFw+h6tS9qIOmIeJY2bx8e7796UgkoLieDQJXGFY5eYYPM53Ksm4r9v/Z8Zhm4Eb/Q8RHVcAwYGlHpB5OZtLckrb4j+kFcj0g0hRXZhSW8UCr2+PPp4gDE7dmJIA==.2kc6T4NPnriT3TQkIlxU1A==<br />
continue=http://www.orkut.com/RedirLogin.aspx?msg=0&amp;page=%2FHome.aspx%3Fxid%3D5239296434780423392&amp;auth=DQAAAIIAAAAnN0_ENJwCttMyPV6Tz6wRh8JSrbvAJzGNB1SWMO65UoC7fcT9CzmmFxFp_SXfesrvrWV0H5e1Amzd8kNe25kFDhwfsITasPcXHQ0oX4qzzQ1eyJvixiCrb8oN_agAE5WSaY150HBhdzwhFx8RwuTkAHz6y2SwdCjursc_NgaTvGZD2mbkRwSdEJ_erYroUNE<br />
the sidt, well, cant say much, except that it looks encoded before just being a session id. Those ==, doesnt that remind us of base64 encoding? Well, this looks sumthing “like” that (no, it aint base64). Its to make sure that the page isnt requested directly, but only after Checkcookie, which is fair enough, since it seems rather hard to guess the sidt<br />
The continue part now seems to look interesting though. Lets de-hex it once more-<br />
http://www.orkut.com/RedirLogin.aspx?msg=0&amp;page=/Home.aspx?xid=5239296434780423392&amp;auth=DQAAAIIAAAAnN0_ENJwCttMyPV6Tz6wRh8JSrbvAJzGNB1SWMO65UoC7fcT9CzmmFxFp_SXfesrvrWV0H5e1Amzd8kNe25kFDhwfsITasPcXHQ0oX4qzzQ1eyJvixiCrb8oN_agAE5WSaY150HBhdzwhFx8RwuTkAHz6y2SwdCjursc_NgaTvGZD2mbkRwSdEJ_erYroUNE</p>
<p>Did some research on this part now, since this looks like the entry point to orkut login system. The auth which was issued by ServiceLoginBoxAuth was used throughout.<br />
Now this is probably a backend part of the script. You see the xid, right. Well, that might be a token id issued by ServiceLoginAuthBox . RedirLogin.aspx probably sends the data it gets from the query string to google servers, to check that firstly, the auth is correct; This is kinda like a checksum/session_id(for the login part). The xid is probably first checked against that auth on the google server, and then the profile id is probably returned.<br />
Once thats done, then orkut loads up a session cookie (along with sum other additional stuff) as okrut_state, which contains multiple parameters. Yup, thats right, 1 cookie, various things, but eventually, a nice session id.. its like various fields with : as the delimiter-</p>
<p>ORKUTPREF=ID=[Session id]<br />
INF=0<br />
SET=[some other number]<br />
LNG=[no clue, but looks boolean]<br />
CNT=[country telephone code. Like mines 91 for india):RM=(probably remember option):<br />
USR=[login email address] (base 64 encoded)<br />
PHS=[no clue of this, since it was blank for me]<br />
TS=[no clue of this, since it was blank for me]<br />
LCL=[Language]<br />
NET=[prob the type of connection- direct or via proxy (depending on proxy-alive header)]<br />
TOS=[clueless]<br />
GC=[AHA, the google auth]<br />
 <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> E=[Again the login address?] (base 64 encoded)<br />
GTI=[some boolean value, perhaps a preference or sumthing]:<br />
GID=[login email address] (base 64 encoded) (again?)<br />
VER=[version?]<br />
S=[dunno <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> ]</p>
<p>And then, the backend body removes the auth from the outstanding list, after logging into the service. (confirmed)</p>
<p>So thats about how orkut login takes place.<br />
(I know the last part was especially shabby, but I thought I would continue this is another blog entry)</p>
<p>W00t! I got r00t!</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/crackintheriver.wordpress.com/3/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/crackintheriver.wordpress.com/3/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/crackintheriver.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/crackintheriver.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/crackintheriver.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/crackintheriver.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/crackintheriver.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/crackintheriver.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/crackintheriver.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/crackintheriver.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/crackintheriver.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/crackintheriver.wordpress.com/3/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=crackintheriver.wordpress.com&blog=1341848&post=3&subd=crackintheriver&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://crackintheriver.wordpress.com/2007/07/08/orkutgoogle-login-schemas/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/19318262334355190171496b623c1704?s=96&#38;d=identicon" medium="image">
			<media:title type="html">silverlightning</media:title>
		</media:content>

		<media:content url="http://blog.legacy.fh-net.com/wp-includes/images/smilies/icon_smile.gif" medium="image">
			<media:title type="html">)</media:title>
		</media:content>

		<media:content url="http://blog.legacy.fh-net.com/wp-includes/images/smilies/icon_smile.gif" medium="image">
			<media:title type="html">)</media:title>
		</media:content>
	</item>
	</channel>
</rss>