Study notes: MAC Spoofing

Study notes are my personal research notes on certain topics that interests me.

Any network capable device has a unique factory-assigned Media Access Control (MAC) address. Users have no way to change the MAC address but it can be done. However, it is possible to mask the MAC address and have it show a different value. This is called MAC spoofing.

There are legitimate uses for MAC spoofing. For example, there may be certain applications that require a particular MAC address to work, or maybe your ISP expects a certain MAC address to connect to the network. MAC spoofing is largely used for illegitimate uses, like circumventing an access control list or getting past a filter on a wireless network.

Changing MAC Address via ifconfig

In Linux we could use ifconfig to change the MAC address.

To view the current MAC address:

$ ifconfig

The current MAC address is 08:00:27:59:fb:fa:

study-notes--mac-spoofing-01

Let's say we want to change the MAC address of our interface (eth0) to 00:11:22:33:44:55.

First, deactivate the interface.

$ ifconfig eth0 down

Then we specify the mac address that we want to change to.

$ ifconfig eth0 hw ether 00:11:22:33:44:55

Reactive the interface:

$ ifconfig eth0 up

Run ifconfig again to see the changes.

study-notes--mac-spoofing-02

NOTE:

These changes are not permanent. The MAC address will return to the original one when the system is restarted!

Changing the MAC address via MACChanger

There are various tools that allows easy changing of MAC addresses. MACChanger is one of them.

First, deactivate the interface.

$ ifconfig eth0 down

The above below allows you specify the mac address you want to use:

$ macchanger -m 00:11:22:33:44:55 eth0

The code below assigns a random MAC address.

$ macchanger -r eth0

Reactive the interface:

$ ifconfig eth0 up

Chicken-Scheme FFI Examples

I'm currently working on refactoring the FFI implementation for the Rebel Game Engine. It was previously written using the Bind chicken egg but I wanted to have more control over the implementation by using the low level foreign functions.

To help me better understand I made some examples that has the basic FFI implementations that I'll be needing for my project.


foreign-lambda example

Let's say we have a structure Vec3 and a function Vec3Create that we want to access from chicken-scheme.

typedef struct Vec3 {
    float x;
    float y;
    float z;
} Vec3;

Vec3* Vec3Create(float x, float y, float z)
{
    Vec3* v = (Vec3*)malloc(sizeof(Vec3));
    v->x = x;
    v->y = y;
    v->z = z;
    return v;
}

We could use foreign-lambda to bind to the function:

(define vec3_create
  (foreign-lambda
    (c-pointer (struct "Vec3"))   ; Return type, a pointer to a struct object of Vec3
    "Vec3Create"                  ; Name fo the function
    float float float))           ; The three parameters (x,y,z) to pass to the function

This would allow us to call the vec3_create function like so:

(vec3_create 1.1 2.2 3.3)

foreign-lambda* example

Let's bind another C function Vec3Print.

void Vec3Print(Vec3 v)
{
    printf("Vec3 to print: (%f, %f, %f)\n", v.x, v.y, v.z);
}

We could also use foreign-lambda* (Notice the asterisk). This is similar to foreign-lambda but accepts C code as a string.

(define vec3_print
  (foreign-lambda*
    void                          ; The return type
    (((c-pointer (struct "Vec3")) a0)) ; The parameter to pass, a pointer to a Vec3 object
    "Vec3Print(*a0);"))           ; The C code in string from
                                  ; Vec3Print accepts a non pointer, we dereference it

(vec3_print (vec3_create 1.1 2.2 3.3))   ; Creates a vec3 and prints it

Inline C code in foreign-lambda*

Here's another example using foreign-lambda*. This time there is no predefined C function, but instead we define the code inside the lisp function's body.

(define vec3_zero
  (foreign-lambda*
    (c-pointer (struct "Vec3"))
    ()                            ; Empty variables
    "Vec3* v = (Vec3*)Vec3Create(0.0f, 0.0f, 0.0f); 
    C_return(v);"))               ; Instead of "return", we use "C_return".

(vec3_print (vec3_zero))          ; Calls vec3_zero and prints the returned Vec3

Note that due to obscure technical reasons C_return must be used instead of return when returning a value. More info about this here.


Free-ing Vec3 pointers

Since Vec3Create allocates memory for a Vec3 struct using malloc, it's a good idea to free this when we are done using it. To do this we could bind a function to free.

(define free (foreign-lambda void "free" c-pointer))

(let ((v (vec3_zero)))
  (vec3_print v)
  (free v))

Setting up getters and setters

If we want to have access to variables of a struct object. We could do something like this:

(define vec3_x
  (foreign-lambda*
    float
    (((c-pointer (struct "Vec3")) a0))
    "C_return(a0->x);"))

(display (vec3_x (vec3_create 8.8 8.8 8.8)))

Now this is fine but it'll be a pain to specify an accessor for every variable. A better solution is to use the foreigners egg which allows the use of macros that will make our lives easier.

(import (chicken foreign))
(import foreigners)

;; Set up the accessors for Vec3 struct
(define-foreign-record-type (vec3 Vec3)
  (float x vec3_x vec3_x!)   ; vec3_x is a getter, vec3_x! is a setter
  (float y vec3_y vec3_y!)
  (float z vec3_z vec3_z!))

(let ((v (vec3_create 4.4 5.5 6.6)))
  (display (vec3_x v)) ; Display value of x
  (newline)

  (vec3_x! v 7.7)      ; Set x to 7.7
  (display (vec3_x v)) ; Display value of x
  (newline)

  (free v))

Binding enums

The foreigners egg also allows for the binding of enums using define-foreign-enum-type. Say we have an enum declaration Keys.

enum Keys {
  UP = 0,
  RIGHT = 1,
  DOWN = 2,
  LEFT = 3
};

:::scheme
(define-foreign-enum-type (keys int)
  (keys->int int->keys)
  ((up keys/up) UP)
  ((right keys/right) RIGHT)
  ((down keys/down) DOWN)
  ((left keys/left) LEFT))

(display keys/right)
(display keys/down)

These are the basic FFI implementations that I have explored. It should be enough for most uses. The example project with working code can be found on Github.

Also, check out the chicken-bind egg, it already has all of the code above conveniently in one package. If you don't need full control and just want a simple FFI solution then this is what you need.

#5 - Switching from C/C++ to C

After the recent changes to the lisp side of my engine, I took some time to review the C/C++ side. You'll notice that I have written C/C++ and that's because my codebase uses both of them.

When I started my project, I initially intended for it to use just pure C, as this is the one I'm more familiar with. But over time some C++ features crept in. Features like namespacess, bools, and function overloading proved to be useful so I kept using them. Now my code uses C concepts with new nifty C++ features.

Now, I could have just continued with this approach. It works, after all. But I wondered if I should just stick to C and drop C++ altogether. My thinking is that sticking with just one language would make the code simpler as I only have to use it's subset of features. I know it's not a solid reason but I figured it's better to act now while it is still early.

switching-from-c-c---to-c-01

For the most part, dropping C++ was easy. Most of the difficulty I encountered was making sure the changes worked on all three supported platforms. There was a situation when I thought I was done only to find it doesn't work on Mac and Windows. I had to slowly re-apply the changes just to see where exactly things went wrong.

What's funny is that I learned that I was using a lot more C++ features than I thought. Namespaces and default arguments are some that really surprised me. I always assumed they were supported on both languages. This just proves to me that I still have a lot to learn with these languages.

I also took the chance during the transition to switch from GLM, an OpenGL Mathematics lirary using C++, to CGLM a similar library that uses C. It is claimed that the latter is more optimized and, with it being in C, is easier to integrate with my codebase.

While these changes did not do much in terms of progress, I am happy that my codebase now feels tighter and more coherent. I'm hoping to work on something engine-related next.

If you are interested to check out my still-under-construction game engine, you can do so here.