Spoofing Source IPs in UDP Packets
Spoofing IP addresses in packets is something that is typically associated with malicious intent, and consequently, is something that is hard to find documentation on. However, there are sometimes genuine needs to spoof IP headers on packets. For instance, in a project I’m working on we have roughly 40 detectors, each with their own IP address, that are going to be streaming UDP packets to a control computer collecting data. In order to test the data collection software, we have an emulator that can emulate one detector, however due to time stamp synchronization requirements, we can’t run 40 instances of the emulator, we have to run 1 instance and then make 40 copies of the resulting UDP stream. In order to make 40 copies of the stream, we also need to make it look like each copy is coming from its own source, which requires that we use IP spoofing.
The main hurdle with IP spoofing is that the kernel networking stack is what stamps the IP header onto a packet before it gets sent off to its destination. What we need our code to do is tell the kernel not to stamp an IP header on the packet, and instead to use headers that we provide. Fortunately, this is possible using raw sockets. A raw socket is a network socket just like a regular TCP or UDP socket, except that it allows direct access to packet headers. Other than a few special code changes, the code is fairly similar to a normal UDP socket. The first step to create a raw socket is to make a call to socket() and specify SOCK_RAW as the type.
int socketFd = socket(PF_INET, SOCK_RAW, IPPROTO_UDP);
This socket behaves just like any other, except that you can tell the kernel that you want to be the one to write the IP and UDP headers to packets. To do this, you have to make a call to setsockopt and specify IP_HDRINCL option. In order to work, the following code (and hence your program) has to be run as root:
int yes = 1; if(setsockopt(socketFd, IPPROTO_IP, IP_HDRINCL, &yes, sizeof(yes)) < 0) printf("Could not set IP_HDRINCL!\n");
Lastly, you must fill in two structures and place them in the buffer than you are going to call sendto() with. The first structure is struct ip, which is an IP header, defined as follows:
struct ipheader { unsigned char ip_hl:4, ip_v:4; /* Each member is 4 bits */ unsigned char ip_tos; unsigned short int ip_len; unsigned short int ip_id; unsigned short int ip_off; unsigned char ip_ttl; unsigned char ip_p; unsigned short int ip_sum; unsigned int ip_src; unsigned int ip_dst; };
The names are a bit cryptic, but most are pretty simple:
- ip_hl: The length of the header in 32-bit octets (for instance ip_hl = 5 -> the length of the header is 5*4 bytes = 160 bits). You almost always want to set this to 5, unless you specify other options used for routing and the like.
- ip_v: The IP version. You probably want to use IPv4. IPv6 can be used also, but that is beyond the scope of this article.
- ip_tos: The Type Of Service, it basically controls the priority of the packet. 0×00 is the normal value (i.e. you should probably use that). The first 3 bits control routing priority, the next 4 control the type of service, see here for more info.
- ip_len: The total length of the packet in bytes, including IP header, UDP/TCP/ICMP header, and message payload.
- ip_id: The ID sequence number, used for assembly of fragmented IP datagrams, can be arbitrary.
- ip_ttl: The Time To Live (maximum number of hops), best to just set to the maximum value of 255.
- ip_p: The transport layer protocol, can be TCP (6), ICMP (1), UDP (17), and others, cat /etc/protocols for a complete list.
- ip_sum: A checksum for the header (which must be computer with ip_sum set to 0). You can set this, but it gets overwritten by most kernels anyway, so you can be safe setting it to 0.
- ip_src: IP source address (this is where your spoofed IP goes) in binary format (probably want to use inet_addr). This is in host byte order.
- ip_dst: Same as ip_src, except that this is for the destination.
The second structure is the header for the individual protocol that you’re going to be using, in this case struct udphdr. Fortunately this structure is much simpler:
struct udpheader { unsigned short int uh_sport; unsigned short int uh_dport; unsigned short int uh_ulen; unsigned short int uh_sum; }
- uh_sport: The source port in network byte order (can be spoofed value).
- uh_dport: The destination port in network byte order (needs to be where you actually want packet to go).
- uh_ulen: The length of the udp packet header and the message payload in bytes in network byte order.
- uh_check: A checksum of the UDP header (again, this will be set by the kernel network stack, so a 0 value is probably okay).
Once you fill in these structure and create a buffer of the form:
You can call sendto() just like you would for any other socket and your packet will appear to come from the spoofed source.
There are a few caveats of course:
- If you spoof the IP of something like a router (e.g. 192.168.0.1), there is a good possibility that your packet isn’t going to get delivered because the router will drop it.
- If you networking stack doesn’t set the correct sum on the packet, or the header is in any way malformed, there is a very good chance the packet will get dropped either at the next router or at the destination.
- There is a lot of protection against IP spoofing in big networks (for instance external packets coming in with internal IPs will probably get dropped), so you have to be careful how and where you’re using this code as it may cause packets to get dropped.
- IP spoofing has a lot of malicious applications, so use it responsibly.
Also, in this article I’ve only covered spoofing UDP source IP addresses. Spoofing TCP and ICMP headers is very similar, except TCP is a little bit more complicated since it is not a connectionless protocol like UDP. Both of these protocols are beyond the scope of this article, but documentation is available online.
C++: Sorting the Contents of an Array Based on the Contents of Another
I often find while programming that I want to sort the contents of one array based on that of another. For instance, say I had the arrays
int rankings[] = {1,4,2,5,3} string names[] = {"George", "Fred", "Gary", "John", "Bob"}
and I wanted to resort both arrays based on ranking. That is, I would want the following result:
int rankings[] = {1,2,3,4,5} string names[] = {"George", "Gary", "Bob", "Fred", "John"}
Now in Python, this would be easy to do.
rankings = [1, 4, 2, 5, 3] names = ["George", "Fred", "Gary", "John", "Bob"] toSort = zip(rankings, names) toSort.sort() rankings, names = zip(*toSort)
Unfortunately you can’t zip C arrays or C++ STL containers up like that. There is probably some mechanism for doing so using Boost, but I figured it would be better to just use the standard C++ algorithms and iterators. I thus present the following code (dualsort.h):
#pragma once #include <algorithm> #include <stdexcept> #include <vector> #include <utility> namespace xenoscope { namespace utility { template <class Compare, class RandomAccessIterator> struct dual_sort_compare_wrapper { dual_sort_compare_wrapper(Compare comparer) : _comparer(comparer) { } bool operator() (std::pair<size_t, RandomAccessIterator> x, std::pair<size_t, RandomAccessIterator> y) { return _comparer(*x.second, *y.second); } Compare _comparer; }; template <class T> struct dual_sort_basic_compare { bool operator() (T x, T y) { return x < y; } }; template <class IndexIterator, class RandomAccessIterator, class OutputRandomAccessIterator> void index_shuffle_copy(IndexIterator begin, IndexIterator end, RandomAccessIterator toSort, OutputRandomAccessIterator output) { while(begin != end) { *output = *(toSort + begin->first); begin++; output++; } } //Unfortunately we have to make a copy buffer. Moving //data in-place would be O(n log n) at minimum, if not more. template <class RandomAccessIteratorType1, class RandomAccessIteratorType2, class Compare> void dual_sort(RandomAccessIteratorType1 it1_begin, RandomAccessIteratorType1 it1_end, RandomAccessIteratorType2 it2_begin, RandomAccessIteratorType2 it2_end, Compare comp) { //Count how many elements we have unsigned n1 = it1_end - it1_begin; unsigned n2 = it2_end - it2_begin; //Do checking if(n1 == 0) { return; } if(n1 < 0) { //We got some messed up values throw std::invalid_argument("First set of iterator arguments are invalid."); } if(n1 != n2) { //The arrays were different sizes throw std::invalid_argument("Containers have different sizes."); } //Create a tracker with indices 0, n1-1 that we can use to see how the //order of the data changed. std::vector<std::pair<size_t, RandomAccessIteratorType1> > order(n1); size_t n = 0; for(RandomAccessIteratorType1 it = it1_begin; it != it1_end; it++, n++) { order[n] = std::make_pair(n, it); } //Do the sorting std::sort(order.begin(), order.end(), dual_sort_compare_wrapper<Compare, RandomAccessIteratorType1 >(comp)); //Order vectors appropriately std::vector<typename std::iterator_traits<RandomAccessIteratorType1>::value_type > copyBuffer1(n1); std::vector<typename std::iterator_traits<RandomAccessIteratorType2>::value_type > copyBuffer2(n2); index_shuffle_copy(order.begin(), order.end(), it1_begin, copyBuffer1.begin()); index_shuffle_copy(order.begin(), order.end(), it2_begin, copyBuffer2.begin()); std::copy(copyBuffer1.begin(), copyBuffer1.end(), it1_begin); std::copy(copyBuffer2.begin(), copyBuffer2.end(), it2_begin); } template <class RandomAccessIteratorType1, class RandomAccessIteratorType2> void dual_sort(RandomAccessIteratorType1 it1_begin, RandomAccessIteratorType1 it1_end, RandomAccessIteratorType2 it2_begin, RandomAccessIteratorType2 it2_end) { dual_sort(it1_begin, it1_end, it2_begin, it2_end, dual_sort_basic_compare<typename std::iterator_traits<RandomAccessIteratorType1>::value_type>()); } } }
This code implements two templated algorithms which extend the standard sort algorithm. They function identically to std::sort, except that they take an extra pair of iterators to a second container which you wanted to be reordered corresponding to the new order in the first container. Here’s an example of how to use it:
#include <vector> #include <string> #include <cstdio> #include "dualsort.h" using namespace std; using namespace xenoscope::utility; int origRankings[] = {1, 4, 2, 5, 3}; string origNames[] = {"George", "Fred", "Gary", "John", "Bob"}; vector<int> rankings; vector<string> names; void printData() { printf("Rankings ordering is:\n"); vector<int>::iterator rit; for(rit = rankings.begin(); rit != rankings.end(); rit++) { printf("\t%i\n", *rit); } printf("Names ordering is:\n"); vector<string>::iterator nit; for(nit = names.begin(); nit != names.end(); nit++) { printf("\t%s\n", nit->c_str()); } printf("\n\n"); } struct ReverseCompare { bool operator() (int i, int j) { return (i > j); } } revComparer; int main() { //Create a dataset rankings = vector<int>(origRankings, origRankings + 5); names = vector<string>(origNames, origNames + 5); printData(); //Sort into ascending order dual_sort(rankings.begin(), rankings.end(), names.begin(), names.end()); printData(); //Sort into descending order using a custom comparer dual_sort(rankings.begin(), rankings.end(), names.begin(), names.end(), revComparer); printData(); return 0; }
It produces the following output:
Rankings ordering is:
1
4
2
5
3
Names ordering is:
George
Fred
Gary
John
Bob
Rankings ordering is:
1
2
3
4
5
Names ordering is:
George
Gary
Bob
Fred
John
Rankings ordering is:
5
4
3
2
1
Names ordering is:
John
Fred
Bob
Gary
George
The code is currently just limited to two containers, but you can easily extend it to more. You can also just make copies of the index vector and call dual_sort for as many vectors as you have. Let me know if you have any trouble with it, or any recommendations. I’m making this code public-domain, so feel free to use it in any project, commercial, open source, whatever. I hate licenses. Credit is of course appreciated, but by no means required.
Downloads:
dualsort.h
Anamnesis Launched
I have just put up the code for a project I’ve been working on called Anamnesis. It is a SIMBL-based plugin for Safari on Mac OS X that adds “Reopen Last Closed Tab” functionality. Please check out the Anamnesis page (see links @ top of page) for more information.
Reading and Parsing USB GPS Data in C (with NmeaLib)
I’m currently working on a project that requires GPS data, and need a way to retrieve data from a USB-based GPS receiver I purchased (a USGlobSat BU-353 USB GPS receiver). Fortunately, most GPS receivers, particularly USB ones, support the NMEA 0183 protocol. NMEA 0183 is a serial-based protocol was developed by the National Marine Electronics Association and is used to collect data from a variety of aquatic electronic devices (such as sonar, GPS, and others). Most USB-based GPS receivers have a serial-to-USB converter built in, which allows data to be read from a device as if it were a serial device. For instance, the BU-353 shows up in Mac OS X as /dev/cu.usbserial. If you plug in your GPS device and boot up minicom, you’ll see output that looks a lot like this
Obviously the strings are somewhat cryptic, but you can discern some data among them that looks like GPS data. Unfortunately the protocol is not open, and costs at least $270 to buy from the NMEA. Fortunately, most of it has been reverse engineered, and there is a great library which already exists to parse these strings into useable data. It is called NmeaLib and it is released under the LGPL. The way it works is that you first initialize it, then just feed it every string that the GPS device feeds you over the serial device, and it will interpret the data and keep a cumulative collection of all available data from the GPS receiver. In addition to the basic latitude and longitude data, it will also report the number of satellites in view, the number satellites being used, the signal strengths of both, as well as the current GPS time and many other useful pieces of information.
The big remaining task once you have the library is to read from the GPS serial device. Reading from a serial device might seem like it would be as simple as reading from a file (and in some ways it is), but because serial port data can come at various rates and in various formats (for instance it might come at 9600 Baud with no parity bit and with 8 bits of data), there are some other calls you need to make to set the various serial settings.
To begin with, we need to get a file descriptor for the serial port. This can be done simply with
gpsFd = open("/dev/cu.usbserial", O_RDONLY | O_NOCTTY | O_NONBLOCK);
You will also need some of the structures and functions included in termios.h, the POSIX terminal definitions, in order to set the appropriate terminal settings.
struct termios options; struct termios origPortOptions; //Get the existing options so they can be restored tcgetattr(gpsFd, &origPortOptions); bzero(&options, sizeof(options)); //Set the BAUD rate to NMEA specifications cfsetospeed(&options, B4800); options.c_cflag |= (CLOCAL | CREAD); //Settings equivalent to 8N1 options.c_cflag &= ~PARENB; //Disabled parity options.c_cflag &= ~CSTOPB; //Set 1 stop bit (| would give us 2 stop bits) options.c_cflag |= CS8; //Set character size to 8 bits options.c_cflag |= CRTSCTS; //Enable hardware flow control options.c_oflag |= (OPOST | ONLCR); //Processed output and mapping of newlines to CR-LF pairs tcsetattr(gpsFd, TCSAFLUSH, &options); //Flush buffers and apply the new settings
After that, you can read from gpsFd like any other file descriptor. If you want to get the number of bytes waiting in the buffer to be read, you can use ioctl() as follows:
int bytesInBuffer; //Get the number of bytes waiting in the serial buffer ioctl(gpsFd, FIONREAD, &bytesInBuffer);
I have attached a simple library (with NmeaLib included) that you can use in your own projects (assuming your serial or USB GPS device uses the same data settings). To use it, you simply call initializeGps(), then get the most recent GPS info by calling getGpsInfo() (which returns an NmeaLib structure). Once you’re finished retrieving GPS data, call closeGps() to free up the serial port and restore its previous settings.
The library uses setitimer() to install an alarm that will call a read handler that will pull all data waiting in the serial buffer and then parse it using NmeaLib. You can change the update frequency if you like, but it is already much faster than it really needs to be, and I’d recommend just leaving it alone as it is very low overhead.
I’ve also included a test program that shows how to use the code in gps.h/.c. Its output looks something like the following:
Yeah so now you know where I live, but I suppose a determined individual could get that from a domain registrar anyway.
Feel free to reuse this code however you see fit, although if you do, some credit is always appreciated. Have fun building those autonomous spy blimps.
keep looking »
