# Pointer Arithmetic / Offsets

**URL:** <https://ziggit.dev/t/pointer-arithmetic-offsets/2633>\
**Category:** Help\
**Created:** [December 29, 2023, 7:16pm UTC](https://ziggit.dev/t/pointer-arithmetic-offsets/2633 "2023-12-29T19:16:26Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![ga-taylorj](https://ziggit.dev/user_avatar/ziggit.dev/ga-taylorj/32/1430_2.png) [@ga-taylorj](https://ziggit.dev/u/ga-taylorj)\
**Post date:** [December 29, 2023, 7:16pm UTC](https://ziggit.dev/t/pointer-arithmetic-offsets/2633/1 "2023-12-29T19:16:26Z")

</div>

I’m implementing a packet parser as a toy project to try and understand Zig better. As part of this I have headers of various sizes and at various offsets into the packet. I’m trying to figure out how I should be approaching this in Zig.

An example of the situation I currently have. In a Ethernet IPv4 packet the second u4 field contains the IHL, this describes how many 32 byte sections exist in the header of the IPv4 packet, after which the body (TCP / UDP etc) will be found.

If I have a pointer to the start of the IPv4 header, how do I gain a pointer to the start of the data section? I thought I’d be able to do this using pointer arithmetic, something along the lines of `dataPtr = ipv4Ptr + (IHL * 4)` where the ptr is a ptr to u8.

I keep getting compilation errors about adding comptime ints or u8 to \*u8 so in the end have gone down the following route of converting to a C ptr, but I feel like I’m doing things very wrong and abusing the language. What’s the proper Zig way of achieving this?

For reference data is a `*const u8` and ihl is a `u4`

```zig
const dataCPtr: [*c]const u8 = @ptrCast(data);
const ipDataPtr = dataCPtr + (@as(u8, ihl) * 4);

```

I did also briefly look at converting the pointer to an Int, doing the arithmetic and then converting back. I think I probably had other errors at the time so may be why I couldn’t get it working.

---

<div class="post-metadata">

**Author:** ![IntegratedQuantum](https://ziggit.dev/user_avatar/ziggit.dev/integratedquantum/32/782_2.png) [@IntegratedQuantum](https://ziggit.dev/u/IntegratedQuantum)\
**Post date:** [December 29, 2023, 7:43pm UTC](https://ziggit.dev/t/pointer-arithmetic-offsets/2633/2 "2023-12-29T19:43:52Z")

</div>

You are using the wrong pointer type for your data.  
Zig has multiple pointer types: [Documentation - The Zig Programming Language](https://ziglang.org/documentation/master/#Pointers)  
You are using a single item pointer here. Because it is intended to always point at a single item it has no pointer arithmetic.

`[*c]` pointers are generally only intended to be used when interfacing with C functions.  
For byte array I would recommend to use a slice `[]const u8` which is pointer plus a length and it can be incremented with the slicing syntax `data[offset..]`.

---

<div class="post-metadata">

**Author:** ![ga-taylorj](https://ziggit.dev/user_avatar/ziggit.dev/ga-taylorj/32/1430_2.png) [@ga-taylorj](https://ziggit.dev/u/ga-taylorj)\
**Post date:** [December 29, 2023, 8:15pm UTC](https://ziggit.dev/t/pointer-arithmetic-offsets/2633/3 "2023-12-29T20:15:37Z")

</div>

Ah so I should have clarified, this is for interop with C, or at least, the data is fetched as a result of interop with C. I’m using libpcap to get packets from my network interface and as such the packet data comes back as a C pointer.

I’d be happy to switch to slices but my headers are variable sizes so not sure how I should be dealing with that. I also don;'t know the overall size of the packet and won’t know until I’ve parsed all the headers. How should I go about converting a C pointer into a slice or slice like structure to enable index based offsets?

---

<div class="post-metadata">

**Author:** ![IntegratedQuantum](https://ziggit.dev/user_avatar/ziggit.dev/integratedquantum/32/782_2.png) [@IntegratedQuantum](https://ziggit.dev/u/IntegratedQuantum)\
**Post date:** [December 29, 2023, 8:22pm UTC](https://ziggit.dev/t/pointer-arithmetic-offsets/2633/4 "2023-12-29T20:22:01Z")

</div>

In that case, since you don’t know the length, then I would suggest to use a multi-item pointer `[*]const u8`. Multi-item pointer allow both pointer arithmetic and slicing.

---

<div class="post-metadata">

**Author:** ![ga-taylorj](https://ziggit.dev/user_avatar/ziggit.dev/ga-taylorj/32/1430_2.png) [@ga-taylorj](https://ziggit.dev/u/ga-taylorj)\
**Post date:** [December 29, 2023, 9:40pm UTC](https://ziggit.dev/t/pointer-arithmetic-offsets/2633/5 "2023-12-29T21:40:03Z")

</div>

Ah makes sense, not sure why I hadn’t thought of that, I’ll give it a go now and see how I get on. May have more questions 🙂
