Final Project 4 - Multi-Core Network Honeypot

FAQ

Updated: 18 May 2010, 3 PM

Resources (7 May)

Here are a few possibly useful resources:

Bugs im mem.c (8 May, 2:45 PM)

A student pointed out these bugs in mem.c. They are now fixed in the /courses/cs3410/p4 files.
  In mem.c:
  In function void free_pages(void *page, unsigned int count):
    int i = (ppn - ram_start_page - pages_reserved);
    if (bitmap_get(page_alloc_bitmap, i) == 1) {
  should be:
    int i = (ppn - ram_start_page - pages_reserved);
    if (bitmap_get(page_alloc_bitmap, i) == 0) {
  In function void free_pages(void *page, unsigned int count):
    unsigned int ppn = paddr / PAGE_SIZE;
    if (ppn < ram_start_page || ppn + count >= ram_end_page) {
  should be:
    unsigned int ppn = paddr / PAGE_SIZE;
    if (ppn < ram_start_page || ppn + count > ram_end_page) {
Here are two more bugs in mem.c: They are now fixed in the /courses/cs3410/p4 files.
  free_pages: missing this line at the bottom of the last while loop: ppn++;
  free: where it says (idx <= 1) it should instead say (idx < 1)

Bug in trap.s (9 May, 1 PM)

A bug was found in the trap handler in trap.s. Three of the temp registers ($8, $9, and $10) were not properly restored before the trap handler returned from an interrupt. The bug has been fixed in the /courses/cs3410/p4 files.

Network Packet Generator and Honeypot Commands (9 May, 1 PM)

A very few of you have noticed that the arriving packets don't seem to have many of the header fields filled out, none seemed bo be "honeypot command packets", and the details of the "honeypot command packets" were a bit vague in the project writeup. This is because we hadn't yet implemented a proper packet generator in the simulator. We have now done so. The 'ksimulate*' simulators in /courses/cs3410/p4 have been updated to generate a more reasonable series of network packets, including honeypot command packets. The command packet format is detailed in the file "honeypot.h", also available in /courses/cs3410/p4.

puts newline (9 May, 1 PM)

According to C standards, puts() is supposed to print a newline after the string. The code in console.c doesn't. You can add it if you like. (Without the fix, GCC optimization can slightly mangle some outputs: GCC actually knows that printf() with a constant string ending in a newline is equivalent to puts() with the same constant but without the newline, and it will take advantage of this when optimizing.)

opcode not supported for LL/SC

Some people are getting gcc errors simililar to this:
  lock.s: Assembler messages:
  lock.s:11: Error: opcode not supported on this processor: mips1 (mips1) `ll $8,($4)'
  lock.s:18: Error: opcode not supported on this processor: mips1 (mips1) `sc $9,($4)'
  make: *** [lock.o] Error 1
Just add the following line before the LL or SC lines:
  .set mips2
Explanation: LL and SC were not part of the MIPS I instruction set architecture. They were added in MIPS II. The simulator only supports MIPS I plus a few bits of MIPS II. So by default, we compile for mips1, but when neded we have to tell gcc that it is okay to use MIPS II instructions by using the above assembler directive for mips2.

Printing doubles (May 13, noon)

Printing double values using printf() does not work due to two bugs: one in printf.c and one in the simulator itself. If you want to be able to print doubles, the files in /courses/cs3410/p4 have been updated. Even so, support for printing doubles is only rudimentary.

Detecting many cores exist (May 13, 1 PM

Several people requested a way to find out how many cores exist from within the simulation. I have added a function current_cpu_exists() that returns a number between 1 and 32 indicating how many cores there are. I have also extended (in the ksimulator) and clarified (in kernel.h) the purpose of the set_cpu_enable() and current_cpu_enable() functions, which can now be used to turn on cores or check which cores are running. The updated files are in /courses/cs3410/p4, as usual.

What's with the 0x55555555 values (May 13, 5 PM)

At the start of the simulation, before the kernel is loaded, the simulator fills all of physical memory with 0x55 bytes. This is done for debugging purposes: any time you see 0x55555555 in one of your variables, it is almost certainly due to using uninitialized memory.

Hash code for djb2 (May 14, 3 PM)

Here is code for the djb2 hash function:
unsigned long djb2(unsigned char *pkt, int n)
{
  unsigned long hash = 5381;
  int c;
  for (int i = 0; i < n; i++) {
    c = pkt[i];
    hash = hash * 33 + c;
    //hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
  }
  return hash;
}
Here is a slightly optimized version:
unsigned long djb2(unsigned char *pkt, int n)
{
  unsigned long hash = 5381;
  int i = 0;
  while (i < n-8) {
    hash = hash * 33 + pkt[i++];
    hash = hash * 33 + pkt[i++];
    hash = hash * 33 + pkt[i++];
    hash = hash * 33 + pkt[i++];
    hash = hash * 33 + pkt[i++];
    hash = hash * 33 + pkt[i++];
    hash = hash * 33 + pkt[i++];
    hash = hash * 33 + pkt[i++];
  }
  while (i < n)
    hash = hash * 33 + pkt[i++];
  return hash;
}

Simulator options (May 14, 3 PM)

The simulator can be configured as an N-way multi-core machine, and you can also control how much memory and network traffic is simulated. Here is the usage:
      Usage: ksimulate [options] <kernel> [bootparams]
      Options can be:
        -d          Use interactive debugger
        -s <n>      Printing status message every <n> cycles
        -f          Turn all exceptions and system calls into fatal errors
        -r <n>      Seed the simulation's random number generator with integer <n>
        -c <n>      Simulate an <n>-way multi-core machine
        -m <n>      Simulate <n> MB of physical RAM
        -t <n>      Simulate <n> MBit/s of network traffic (can be fractional, e.g. 0.25)
        -i <file>   Use <file> as the simulate keyboards device's input rather than the real keyboard
        -o <file>   Use <file> as the simulate console device's output rather than the real console
      
      The [bootparams] option can be any number of strings to be made available to the kernel.
      
      Verbose simulator messages:
        -v          Turn on verbose messages for all types of simulator actions.
        -v:<type>   Turn on verbose messages for one <type> of simulator action,
                    where <type> is one of: boot, mmu, llsc, net, trap, or all.
      The verbose options can be repeated to get even more messages, and the types
      can be added together. E.g., use '-vvvvv:llsc,mmu' for very verbose messages
      about load linked / store conditional instructionss and the actions of the
      simulated virtual memory MMU.

LL/SC lock contention and a simulator update (May 14, 11 PM)

It was noticed that store conditional (SC) seems to fail more often than strictly necessary. Indeed, the simulator makes SC fail if any other core touches the same physical memory location, even if just reading it. This makes mutexes using LL and SC a bit more expensive than perhaps necessary, since the when two or more cores are trying to take the mutex both will repeatedly do LL then both get a failure on SC.

I have changed the simulator to be a bit more conservative in making store conditional (SC) fail: it will now only fail if another core writes to the same physical address. The ksimulator* files in /courses/cs3410/p4 have been updated.

Note that both the new and old simulator behaviors are acceptable according to the MIPS standard: SC can fail for essentially any reason the hardware designer desires, including completely arbitrary reasons. This means any code using LL/SC that was correct for the old simulator will still be correct for the new simulator, just more efficient and higher performance.

Clarification: the whole packet should be hashed (May 16, 9 PM)

When hashing a packet, the whole packet should be hashed, headers and all, exactly as it arrived from the network card.

Calloc bug (May 16, 9 PM)

A bug has been reported in mem.c's implementation of calloc. The code correctly allocates (size*count) bytes, but then only clears (size) bytes to zero. The function should clear all (size*count) bytes to zero. The code in /courses/cs3410/p4 has been fixed.

Network device simulation bug (May 16, 10 PM)

A bug has been discovered in the way the network device simulates DMA. If the ring datastructure or the empty buffers in the ring start in the lower half of a physical page, DMA would work correctly. But if they start in the upper half of a page, the DMA would access the wrong physical address. A corrected ksimulate* has been placed in /courses/cs3410/p4.

ksimulate source code (May 16, 10 PM)

By request, the source code to the simulator itself is now available in /courses/cs3410/p4/src/.

memcpy is double slow (May 17, 4 PM)

It has been pointed out that mem.c's implementation of memcpy() is silly: it copies the data twice. You can delete one of the two for loops. The file in /courses/cs3410/p4 has been updated.

printing 64-bit long long variables (May 18, noon)

If you want to be able to print 64 bit variables ("long long" or "unsigned long long"), the existing printf code does not work. I have posted new code to support printing 64 bit variables. Now printf.c supports "%lld", "%llu", "%llx", and "%llX". There are also two new files needed for this: libgcc2.c and longlong.h, and libgcc2.c must get added to the Makefile. All these changes are in /courses/cs3410/p4, as usual.

Delete vulnerable port command is buggy (May 18, 3 PM

The honeypot command to delete a vulnerable port from the list had a bug: the data for these command packets was not a reasonable port number. The ksimulate* files in /courses/cs3410/p4 have been fixed.