# Help with custom packets over raw sockets

**URL:** <https://discourse.julialang.org/t/help-with-custom-packets-over-raw-sockets/95205>\
**Category:** General Usage\
**Tags:** question, networking\
**Created:** [February 25, 2023, 9:08pm UTC](https://discourse.julialang.org/t/help-with-custom-packets-over-raw-sockets/95205 "2023-02-25T21:08:46Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Fragamir](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fragamir/32/36135_2.png) [@Fragamir](https://discourse.julialang.org/u/Fragamir)\
**Post date:** [February 25, 2023, 9:08pm UTC](https://discourse.julialang.org/t/help-with-custom-packets-over-raw-sockets/95205/1 "2023-02-25T21:08:46Z")

</div>

Hi,

I’m trying to write some custom packets (That I have already created and verified they are valid) to the network, I have tried using both tap interfaces and raw sockets.

I created the raw socket following this thread [Linux raw socket](https://discourse.julialang.org/t/linux-raw-socket/91044), I can read packets from this io, but when I try to write packets to it they don’t seem to make it onto the network (I am observing with wireshark if that makes a difference) - Can anybody provide me with some insight on why this isn’t working? It currently blocking the progression of my dissertation project…

Thanks.

---

<div class="post-metadata">

**Author:** ![Fragamir](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fragamir/32/36135_2.png) [@Fragamir](https://discourse.julialang.org/u/Fragamir)\
**Post date:** [February 27, 2023, 4:27pm UTC](https://discourse.julialang.org/t/help-with-custom-packets-over-raw-sockets/95205/2 "2023-02-27T16:27:14Z")

</div>

I have resolved this, and figure I will leave my solution here for the next person.

Firstly we create the socket:

```julia
function get_socket()::IOStream
    #fd = ccall(:socket, Cint, (Cint, Cint, Cint), AF_PACKET, SOCK_RAW, hton(IPPROTO_RAW))
    fd = ccall(:socket, Cint, (Cint, Cint, Cint), Int32(17), Int32(3), 0xff00)
    if fd == -1
        @error "Failed to open socket" errno=Base.Libc.errno()
    end
    return fdio(fd)
end

```

Then in order to send data we need to use the **sendto()** function [sendto(2)](https://linux.die.net/man/2/sendto), and to do that across a connectionless socket (like a raw socket) you’ll need to create a sockaddr\_ll struct:

```julia
struct Sockaddr_ll
    sll_family::Cushort
    sll_protocol::Cushort
    sll_ifindex::Cint
    sll_hatype::Cushort
    sll_pkttype::Cuchar
    sll_halen::Cuchar
    sll_addr::NTuple{6, Cuchar}
end

```

and the sendto ccall too:

```julia
    bytes = ccall(:sendto, Cint, (Cint, Ptr{UInt8}, Csize_t, Cint, Ptr{Sockaddr_ll}, Cint), sockfd, packet, length(packet), 0, Ref(sockaddr_ll), sizeof(sockaddr_ll))

```

where sockfd is the output of get\_socket(), packet is a Vector{UInt8}.

In my implementation I have hard-coded the values of Sockaddr\_ll (other than interface and addr):

```julia
    function Sockaddr_ll(;
        sll_family::Cushort=hton(UInt16(3)),#hton(AF_PACKET),
        sll_protocol::Cushort=hton(0x0800),#hton(ETH_P_IP),
        sll_ifindex::Cint, # Interface id here
        sll_hatype::Cushort=hton(Cushort(1)),#hton(ARPHRD_ETHER),
        sll_pkttype::Cuchar=Cuchar(0), # This field doesn't matter for sending packets
        sll_halen::Cuchar=Cuchar(6),#ETH_ALEN,
        sll_addr::NTuple{6, Cuchar} # Mac address here
    )
        new(sll_family, sll_protocol, sll_ifindex, sll_hatype, sll_pkttype, sll_halen, sll_addr)
    end

```

You can use the **if\_nametoindex** function from c to get the interface name.
