tag:blogger.com,1999:blog-8577871288924093307.post60446710071297677..comments2019-08-08T06:31:05.817-04:00Comments on [ List || List <- "Incomprehension" ].: ICMP Ping in Erlang, part 2Unknownnoreply@blogger.comBlogger20125tag:blogger.com,1999:blog-8577871288924093307.post-42316109545668934782011-12-13T16:36:54.988-05:002011-12-13T16:36:54.988-05:00perfect !perfect !benhttps://www.blogger.com/profile/14211460427643868378noreply@blogger.comtag:blogger.com,1999:blog-8577871288924093307.post-52470827361717928642011-12-12T18:26:36.672-05:002011-12-12T18:26:36.672-05:00From this:
=ERROR REPORT==== 12-Dec-2011::23:04:3...From this:<br /><br />=ERROR REPORT==== 12-Dec-2011::23:04:34 ===<br />Error in process <0.45.0> with exit value: {undef,[{pkt,icmp,[{icmp,8,0,0,123,0,{127,0,0,1},<<4 bytes>>,0,0,0,0,0}]},{gen_icmp,packet,2},{gen_icmp,'-ping/3-fun-0-',5}]}<br /><br />It looks as if you don't have the pkt library. It should have been downloaded as a dependency by rebar (to the deps directory).<br /><br />Try doing a make clean; make in gen_icmp or do a clone of pkt in deps.Michael Santoshttps://www.blogger.com/profile/04190253757527899078noreply@blogger.comtag:blogger.com,1999:blog-8577871288924093307.post-36305678564103605372011-12-12T18:11:35.362-05:002011-12-12T18:11:35.362-05:00thx , that fixed the build , now getting a runtime...thx , that fixed the build , now getting a runtime issue :<br />see same gist for4an update :<br />git@gist.github.com:20952a23e9c392fe3f04.gitbenhttps://www.blogger.com/profile/14211460427643868378noreply@blogger.comtag:blogger.com,1999:blog-8577871288924093307.post-44880193518014566492011-12-12T17:42:29.152-05:002011-12-12T17:42:29.152-05:00Hey Ben, it looks as if your shell is picking up a...Hey Ben, it looks as if your shell is picking up an older version of Erlang (/usr/lib/erlang/erts-5.7.4/include/erl_nif_api_funcs.h). Try putting the path to the R14B04 erl at the front of your PATH.<br /><br />If you still get a compile error, try updating procket from git.<br /><br />Hope that works for you and be sure to let me know if you have any questions!Michael Santoshttps://www.blogger.com/profile/04190253757527899078noreply@blogger.comtag:blogger.com,1999:blog-8577871288924093307.post-44987065293558577822011-12-12T17:21:48.149-05:002011-12-12T17:21:48.149-05:00here it is :
git@gist.github.com:20952a23e9c392fe3...here it is :<br />git@gist.github.com:20952a23e9c392fe3f04.gitbenhttps://www.blogger.com/profile/14211460427643868378noreply@blogger.comtag:blogger.com,1999:blog-8577871288924093307.post-29987153530173296452011-12-09T20:13:42.237-05:002011-12-09T20:13:42.237-05:00Hey Ben!
Yes, it should work with R14B04. What er...Hey Ben!<br /><br />Yes, it should work with R14B04. What errors are you getting? (And 16 cores ... nice! :)Michael Santoshttps://www.blogger.com/profile/04190253757527899078noreply@blogger.comtag:blogger.com,1999:blog-8577871288924093307.post-43418770289000577992011-12-09T19:10:03.095-05:002011-12-09T19:10:03.095-05:00hello Michael,
is it suppose to build using :
Er...hello Michael,<br /><br />is it suppose to build using :<br /><br />Erlang R14B04 (erts-5.8.5) [source] [64-bit] [smp:16:16] [rq:16] [async-threads:0] [kernel-poll:false]benhttps://www.blogger.com/profile/14211460427643868378noreply@blogger.comtag:blogger.com,1999:blog-8577871288924093307.post-25688040752739444142011-08-22T13:29:12.398-04:002011-08-22T13:29:12.398-04:00Hey Witold!
That sounds like an awesome project!
...Hey Witold!<br /><br />That sounds like an awesome project!<br /><br />> I was wondering what performance overheads your libraries and interfaces<br />> incure compared to native kernel performance?<br /><br />Hard to say but same problems and (maybe) similar performance as other network stacks running in user space like OpenVPN or Qemu/KVM (both of these use tun/tap).<br /><br />Here are some old iperf results. The test was first run directly to the server (192.168.213.7) over 802.11 and then across a tunnel set up between the client and the server (10.11.11.2).<br /><br />The tunnel runs over the Erlang distribution protocol. Here's the code:<br /><br />https://gist.github.com/1020605<br /><br />It uses tunctl to configure the interfaces:<br /><br />https://github.com/msantos/tunctl<br /><br />No idea what these results demonstrate, except maybe that the tunnel doesn't crash under this amount of load.<br /><br />[Run 1]<br /><br />[client to server over 802.11]<br />$ iperf -c 192.168.213.7<br />------------------------------------------------------------<br />Client connecting to 192.168.213.7, TCP port 5001<br />TCP window size: 16.0 KByte (default)<br />------------------------------------------------------------<br />[ 3] local 192.168.213.119 port 37025 connected with 192.168.213.7 port 5001<br />[ ID] Interval Transfer Bandwidth<br />[ 3] 0.0-10.3 sec 8.75 MBytes 7.14 Mbits/sec<br /><br />[client to server tunnelled over distribution]<br />$ iperf -c 10.11.11.2<br />------------------------------------------------------------<br />Client connecting to 10.11.11.2, TCP port 5001<br />TCP window size: 16.0 KByte (default)<br />------------------------------------------------------------<br />[ 3] local 10.11.11.1 port 58447 connected with 10.11.11.2 port 5001<br />[ ID] Interval Transfer Bandwidth<br />[ 3] 0.0-10.5 sec 7.07 MBytes 5.66 Mbits/sec<br /><br /><br />[Run 2]<br /><br />[client to server over 802.11]<br />$ iperf -c 192.168.213.7<br />------------------------------------------------------------<br />Client connecting to 192.168.213.7, TCP port 5001<br />TCP window size: 16.0 KByte (default)<br />------------------------------------------------------------<br />[ 3] local 192.168.213.119 port 40688 connected with 192.168.213.7 port 5001<br />[ ID] Interval Transfer Bandwidth<br />[ 3] 0.0-10.0 sec 13.5 MBytes 11.3 Mbits/sec<br /><br />[client to server tunnelled over distribution]<br />$ iperf -c 10.11.11.2<br />------------------------------------------------------------<br />Client connecting to 10.11.11.2, TCP port 5001<br />TCP window size: 16.0 KByte (default)<br />------------------------------------------------------------<br />[ 3] local 10.11.11.1 port 35319 connected with 10.11.11.2 port 5001<br />[ ID] Interval Transfer Bandwidth<br />[ 3] 0.0-10.1 sec 10.6 MBytes 8.83 Mbits/sec<br /><br />> Will it scale to multi-core?<br /><br />Depends on your code. Most operations involve doing sequential reads/writes from a file descriptor. This will run on only one core.<br /><br />But, for example, say you were writing a firewall. One process could read packets from the network. You could compile groups of firewall rules to Erlang modules and run each set of rules as a filter process. These processes could run on other cores or on other nodes using distribution.<br /><br />I played with something similar for snort rules and it seemed to work ok.<br /><br />> Is it asynchronous or synchronous?<br /><br />Has to be async, otherwise the Erlang scheduler will be blocked. For simplicity, some of the interfaces presented to the caller are blocking though. Something along the lines of:<br /><br />read(Socket) -><br /> case procket:read(Socket, 16#FFFF) of<br /> {ok, Data} -> {ok, Data};<br /> {error, eagain} -><br /> timer:sleep(10),<br /> read(Socket);<br /> Error -> Error<br /> end.<br /><br />> What are advantages / disanvantages of nif vs ports here?<br /><br />Either would work really. Using a port running as a Unix process would involve some overhead passing the fd back and forth to beam over a Unix socket.Michael Santoshttps://www.blogger.com/profile/04190253757527899078noreply@blogger.comtag:blogger.com,1999:blog-8577871288924093307.post-42016650309905117742011-08-21T19:38:34.986-04:002011-08-21T19:38:34.986-04:00Hi, I'm thinking about writing Erlang based ip...Hi, I'm thinking about writing Erlang based ipv4/ipv6, router with firewall, connection tracking (icmp/udp/tcp), NAT44, NAT66, NAT46, sit tunnels, and few other things. I was wondering what performance overheads your libraries and interfaces incure compared to native kernel performance? Will it scale to multi-core? Is it asynchronous or synchronous? What are advantages / disanvantages of nif vs ports here?<br /><br />Thanks in advance. Lots of cool and good work you have done!Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-8577871288924093307.post-80917685315147924572011-08-05T09:26:25.637-04:002011-08-05T09:26:25.637-04:00Michael, thak you very much for your help! :) Now ...Michael, thak you very much for your help! :) Now it works just fine.<br /><br />So now I'm really looking forward for having traceroute implemented in gen_icmp library :)Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-8577871288924093307.post-43005815887382640432011-08-05T08:55:49.909-04:002011-08-05T08:55:49.909-04:00Looks like you setcap the smp beam but are running...Looks like you setcap the smp beam but are running the non-smp beam. So either:<br /><br />erl -smp<br /><br />or<br /><br />sudo setcap 'cap_net_raw=ep' /usr/local/lib/erlang/erts-5.8.4/bin/beamMichael Santoshttps://www.blogger.com/profile/04190253757527899078noreply@blogger.comtag:blogger.com,1999:blog-8577871288924093307.post-20084876958855950842011-08-05T07:15:33.677-04:002011-08-05T07:15:33.677-04:00It didn't help. Now I have the same error in ...It didn't help. Now I have the same error in gen_icmp:open/2 call.<br /><br /><br />Erlang R14B03 (erts-5.8.4) [source] [64-bit] [rq:1] [async-threads:0] [kernel-poll:false]<br /><br />Eshell V5.8.4 (abort with ^G)<br />1> {ok, Socket} = gen_icmp:open([{setuid,false}], []).<br />** exception exit: {badmatch,{error,eperm}}<br /> in function gen_icmp:init/1<br /> in call from gen_server:init_it/6<br /> in call from proc_lib:init_p_do_apply/3Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-8577871288924093307.post-42233077416987233452011-08-03T10:31:42.677-04:002011-08-03T10:31:42.677-04:00For using gen_icmp with the capability set, you ha...For using gen_icmp with the capability set, you have to use the long form (ping/3):<br /><br />{ok, Socket} = gen_icmp:open([{setuid,false}], []),<br />gen_icmp:ping(Socket, ["www.google.com"], []).<br /><br />If you want to use ping/1, set up sudo:<br /><br />sudo visudo<br /> ALL = NOPASSWD: /path/to/procket/priv/procketMichael Santoshttps://www.blogger.com/profile/04190253757527899078noreply@blogger.comtag:blogger.com,1999:blog-8577871288924093307.post-25001608204427149032011-08-03T07:39:26.094-04:002011-08-03T07:39:26.094-04:001. Pure logic is prompting that in gen_icmp module...1. Pure logic is prompting that in gen_icmp module it's cool to have an ICMP traceroute implementation at first hand. :) And then UDP version :)<br /><br />2. I'll try it out. Thanks for a hint. <br /><br />3. I ran following commands:<br /><br />$ sudo setcap 'cap_net_raw=ep' /usr/local/lib/erlang/erts-5.8.4/bin/beam.smp<br /><br />$ getcap /usr/local/lib/erlang/erts-5.8.4/bin/beam.smp<br />/usr/local/lib/erlang/erts-5.8.4/bin/beam.smp = cap_net_raw+ep<br /><br />and still have that:<br /><br />Eshell V5.8.4 (abort with ^G)<br />1> gen_icmp:ping("google.com").<br />** exception exit: {badmatch,{error,eperm}}<br /> in function gen_icmp:init/1<br /> in call from gen_server:init_it/6<br /> in call from proc_lib:init_p_do_apply/3<br /><br />I use Ubuntu Linux 11.04 and configured by default Erlang.<br /><br />May be I should set cap_net_raw permissions to some other files?Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-8577871288924093307.post-43512904677866752052011-08-02T12:50:06.259-04:002011-08-02T12:50:06.259-04:00Hey there!
1. Sure, having UDP and ICMP probes wo...Hey there!<br /><br />1. Sure, having UDP and ICMP probes would be nice and wouldn't be much more work. Which would you want working first though?<br /><br />I'm planning on adding IPv6 support. The library gen_icmp uses to interact with sockets (procket) was updated a few months ago to support IPV6, so sending IPv6 ICMP packets should work from Erlang if you call procket directly.<br /><br />2. Sorry, I forgot gen_icmp uses the raw socket interface. The IP header is added by the OS in this case. This behaviour can be changed by using the HDRINCL socket option, something like (untested):<br /><br /> -define(IP_HDRINCL, 3).<br /><br /> {ok, Socket} = procket:open(0, [{protocol, icmp}, {type, raw}, {family, inet}]),<br /> ok = procket:setsockopt(Socket, ?IPPROTO_IP, ?IP_HDRINCL, <<1:32/native>>),<br /><br /> Packet = list_to_binary([<br /> #ipv4{ ttl = 1},<br /> ...<br /> ]).<br /><br />3. So under Linux, you can either give beam the CAP_NET_RAW capability or use sudo to run the procket helper binary (or make it setuid).<br /><br />The gen_icmp and procket READMEs have instructions to set it up:<br /><br />https://github.com/msantos/gen_icmp/blob/master/README.md<br /><br />https://github.com/msantos/procket/blob/master/README.md<br /><br />If any of that is unclear, please let me know! Hope this helps!Michael Santoshttps://www.blogger.com/profile/04190253757527899078noreply@blogger.comtag:blogger.com,1999:blog-8577871288924093307.post-48018017306732062532011-08-02T05:36:58.008-04:002011-08-02T05:36:58.008-04:00And there is another question from me :) I tried t...And there is another question from me :) I tried to compile and run gen_icmp:ping("google.com") in Erlang shell (Ubuntu Linux), and it seems that it only works under root privileges otherwise it throws an exception {badmatch, {error, eperm}} in function gen_icmp:init/1.<br /><br />Could it be somehow corrected?Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-8577871288924093307.post-87579195271578604782011-08-02T04:35:40.386-04:002011-08-02T04:35:40.386-04:00I still can't find where it constructs IPv4 he...I still can't find where it constructs IPv4 header in gen_icmp module. I found only packet/2 function where it prepares ICMP packet. <br /><br />Supposing if I want to change TTL for some reason in ping packet where exactly I have to change #ipv4{ ttl = 1 } value?Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-8577871288924093307.post-79939806819716276412011-08-02T02:57:27.770-04:002011-08-02T02:57:27.770-04:00As you know sometimes we need ICMP and sometimes U...As you know sometimes we need ICMP and sometimes UDP version of traceroute. It would really cool to have both of them implemented :)<br /><br />And what about IPv6? ))Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-8577871288924093307.post-82144963573467230382011-08-01T17:37:43.225-04:002011-08-01T17:37:43.225-04:00The use of gen_udp is a bit misleading. It's o...The use of gen_udp is a bit misleading. It's only being used to read/write to the socket. We're constucting the full packet (IPv4 header, ICMP header) by hand.<br /><br />So to set the TTL, just set the value in the IPv4 header. For example, to construct an IPv4 header with a TTL set to 1 using pkt/epcap_net:<br /><br />IP = #ipv4{ ttl = 1 }.<br /><br />See the record definition for IPv4 headers here:<br /><br />https://github.com/msantos/pkt/blob/master/include/pkt.hrl#L134<br /><br />Are you interested in using UDP or ICMP probes for the traceroute? I think adding a traceroute to gen_icmp is a great idea. I'll see if I can put something together.Michael Santoshttps://www.blogger.com/profile/04190253757527899078noreply@blogger.comtag:blogger.com,1999:blog-8577871288924093307.post-75985039715173433532011-08-01T16:23:07.546-04:002011-08-01T16:23:07.546-04:00Here you implemented ping function using gen_udp:s...Here you implemented ping function using gen_udp:send function. If I understand right it's impossible to change TTL value of IP packet with gen_udp. I wonder how the it could be done. I try to understand how traceroute function coul be written in Erlang. Is it possible for you to show an example of Erlang traceroute implementation?Anonymousnoreply@blogger.com