FAQ
I'm writing an Internet management system in Go, replacing and greatly
improving on the current system written in Lua. Lua rocks in its own
right, but this project's future is Go.

In the Lua code I avoided system calls, and instead parsed or edited proc
files or executed external commands to do the work for me. In the new Go
version, I could take the same tack, but I feel I would be missing an
opportunity. I'm hoping an experienced Linux dev would be able to offer
some useful advice.

I'm looking for some suggestions for accomplishing the following:

1) Obtaining a device's hardware address from IP
In Lua, I currently parse /proc/net/arp. Bit of googling indicates that I
want to call SIOCGARP, which go lists
in http://golang.org/pkg/syscall/#pkg-constants as an untyped constant.
But there's a stack of different functions listed in syscall, I'm not sure
what to use, or how to use it. Can anyone provide a simple example?
Ideally it would be nice to use higher level packages such as net, but it
only seems to expose hardware addresses of local interfaces...(which is
useful, just not for this problem).

2) Enable packet forwarding.
In Lua I write 1 to /proc/sys/net/ipv4/ip_forward, which works but, anyone
suggest a better way?

3) Create a new interface, or alter an existing one.
In Lua I run ifconfig eth0:1 <ip>

4) Set nameservers.
In Lua I rewrite /etc/resolv.conf. Is there a better way?

5) Configure firewall
In Lua I call /sbin/iptables. I have doubts as to whether it would be a
good idea to attempt this using syscalls. But if I could pull it off in a
sane way, it would probably help with reading back counters, which I
currently do by regexp matching the output of iptables -L.

I've probably asked way too much in one message, so any tips on any of the
above would be appreciated.

Cheers.




--

Search Discussions

  • Bryanturley at Nov 2, 2012 at 3:28 pm
    Parsing proc might be the simplest way still for the things you where
    already doing from it.
    While the syscalls are generally stable from version to version, they are
    not portable. I would avoid using them directly if you can.

    You would have to add a bunch of the stuff from the linux headers to fully
    support some of these syscalls.
    man syscalls to get a list

    1) I believe /proc/net/arp only temporarily holds macs for addresses you
    have very recently talked to.

    3) ip or ipconfig (deprecated) should work fine.

    4) I believe this is actually part of libc or in our case here go's stdlib
    (might be wrong). They just expect the nameserver to be described in that
    file and read it quite frequently from what I remember.

    5) cgo and some of the libs/docs at
    http://www.netfilter.org/projects/libnfnetlink/index.html this would be a
    big project though.

    Did you check to see if someone has already written some of these
    http://godashboard.appspot.com/ ?

    --
  • Kyle Lemons at Nov 2, 2012 at 3:39 pm

    On Fri, Nov 2, 2012 at 3:48 AM, krolaw wrote:

    I'm writing an Internet management system in Go, replacing and greatly
    improving on the current system written in Lua. Lua rocks in its own
    right, but this project's future is Go.

    In the Lua code I avoided system calls, and instead parsed or edited proc
    files or executed external commands to do the work for me. In the new Go
    version, I could take the same tack, but I feel I would be missing an
    opportunity. I'm hoping an experienced Linux dev would be able to offer
    some useful advice.

    I'm looking for some suggestions for accomplishing the following:

    1) Obtaining a device's hardware address from IP
    In Lua, I currently parse /proc/net/arp. Bit of googling indicates that I
    want to call SIOCGARP, which go lists in
    http://golang.org/pkg/syscall/#pkg-constants as an untyped constant.
    But there's a stack of different functions listed in syscall, I'm not sure
    what to use, or how to use it. Can anyone provide a simple example?
    Ideally it would be nice to use higher level packages such as net, but it
    only seems to expose hardware addresses of local interfaces...(which is
    useful, just not for this problem).
    That's probably still the easiest, but if you want the syscall:

    You will want to do a raw IOCTL
    https://github.com/kylelemons/goat/blob/go.r60/term/termio.go#L167
    but using SIOCGARP
    http://pic.dhe.ibm.com/infocenter/aix/v7r1/topic/com.ibm.aix.commtechref/doc/commtrf2/ioctl_socket_control_operations.htm#ioctl_socket_control_operations
    The argument is an arpreq
    http://www.scs.stanford.edu/histar/src/pkg/uclibc/include/net/if_arp.h

    I'm not sure whether this will actually get you the hwaddr of an IP that's
    not already in the IP table though, so you may have to ping it first or
    something.

    2) Enable packet forwarding.
    In Lua I write 1 to /proc/sys/net/ipv4/ip_forward, which works but, anyone
    suggest a better way?
    either through /proc/, exec'ing to sysctl, or you could use CGO to call
    sysctl() (it's a part of syscall on bsd and darwin, but not linux).

    3) Create a new interface, or alter an existing one.
    In Lua I run ifconfig eth0:1 <ip>
    Definitely shell out to ifconfig. That's not a wheel you want to
    reimplement :).

    4) Set nameservers.
    In Lua I rewrite /etc/resolv.conf. Is there a better way?
    Nope. That's the one.

    5) Configure firewall
    In Lua I call /sbin/iptables. I have doubts as to whether it would be a
    good idea to attempt this using syscalls. But if I could pull it off in a
    sane way, it would probably help with reading back counters, which I
    currently do by regexp matching the output of iptables -L.
    Also a wheel you really don't want to implement.

    I've probably asked way too much in one message, so any tips on any of the
    above would be appreciated.

    Cheers.




    --

    --
  • Minux at Nov 2, 2012 at 3:45 pm
    On Fri, Nov 2, 2012 at 11:39 PM, Kyle Lemons wrote:
    2) Enable packet forwarding.
    In Lua I write 1 to /proc/sys/net/ipv4/ip_forward, which works but,
    anyone suggest a better way?
    either through /proc/, exec'ing to sysctl, or you could use CGO to call
    sysctl() (it's a part of syscall on bsd and darwin, but not linux).
    sysctl is deprecated on Linux, and i think accessing /proc/sys is the
    recommended way to tweak
    sysctl parameters.

    --
  • Ian Lance Taylor at Nov 2, 2012 at 4:42 pm

    On Fri, Nov 2, 2012 at 3:48 AM, krolaw wrote:
    I'm writing an Internet management system in Go, replacing and greatly
    improving on the current system written in Lua. Lua rocks in its own right,
    but this project's future is Go.

    In the Lua code I avoided system calls, and instead parsed or edited proc
    files or executed external commands to do the work for me. In the new Go
    version, I could take the same tack, but I feel I would be missing an
    opportunity. I'm hoping an experienced Linux dev would be able to offer
    some useful advice.
    There is really nothing wrong with the approaches you are already
    taking. And they have the advantage that they are more likely to
    continue working correctly on new kernels. Unless these parts of your
    program are performance sensitive, you may want to simply continue
    what you are doing.

    1) Obtaining a device's hardware address from IP
    In Lua, I currently parse /proc/net/arp. Bit of googling indicates that I
    want to call SIOCGARP, which go lists in
    http://golang.org/pkg/syscall/#pkg-constants as an untyped constant.
    But there's a stack of different functions listed in syscall, I'm not sure
    what to use, or how to use it. Can anyone provide a simple example?
    Ideally it would be nice to use higher level packages such as net, but it
    only seems to expose hardware addresses of local interfaces...(which is
    useful, just not for this problem).
    It sounds like you want the hardware addresses of interfaces on other
    systems. If you already know the IP address of the remote system you
    want to look up, and the name of the interface, and you happen to know
    that the value is already in the ARP cache, then you can use SIOCGARP
    to find the hardware address.

    This program does it on my system, but I hardcoded the IP address and
    network name.

    http://play.golang.org/p/V1gNOEbHMu

    2) Enable packet forwarding.
    In Lua I write 1 to /proc/sys/net/ipv4/ip_forward, which works but, anyone
    suggest a better way?
    You could use the sysctl system call, but frankly writing to /proc
    works just as well.

    3) Create a new interface, or alter an existing one.
    In Lua I run ifconfig eth0:1 <ip>
    No idea. You could strace ifconfig to see what it is doing.

    4) Set nameservers.
    In Lua I rewrite /etc/resolv.conf. Is there a better way? No.
    5) Configure firewall
    In Lua I call /sbin/iptables. I have doubts as to whether it would be a
    good idea to attempt this using syscalls. But if I could pull it off in a
    sane way, it would probably help with reading back counters, which I
    currently do by regexp matching the output of iptables -L.
    I agree that using /sbin/iptables is likely to be the best approach
    for both writing and reading.

    Ian

    --
  • Krolaw at Nov 3, 2012 at 10:03 am
    Hi,

    Thanks to all who responded (Bryan, Kyle, Minux & Ian), the feedback was
    really helpful in validating the current approach. I don't want to make
    things complicated unnecessarily. :-)

    Cheers.


    --

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedNov 2, '12 at 10:48a
activeNov 3, '12 at 10:03a
posts6
users5
websitegolang.org

People

Translate

site design / logo © 2022 Grokbase