Skip to content

Instantly share code, notes, and snippets.

@shun159
Last active October 17, 2016 09:15
Show Gist options
  • Save shun159/f9a922be75804c8d5c5e385642af07be to your computer and use it in GitHub Desktop.
Save shun159/f9a922be75804c8d5c5e385642af07be to your computer and use it in GitHub Desktop.
require 'socket'
require 'pio'
class RawSocket
include Pio
ETH_P_ALL = 0x0300
SIOCGIFINDEX = 0x8933
def initialize(interface)
@socket =
Socket.new(Socket::PF_PACKET, Socket::SOCK_RAW, ETH_P_ALL).tap do |sock|
ifreq = [interface].pack('a32')
sock.ioctl SIOCGIFINDEX, ifreq
sock.bind([Socket::AF_PACKET].pack('s').tap do |sll|
sll << ([ETH_P_ALL].pack 's')
sll << ifreq[16..20]
sll << ("\x00" * 12)
end)
end
end
def udp_send(t = 10, payload = '')
udp = Udp.new(destination_mac: '01:01:01:01:01:01',
source_mac: '00:0b:82:01:fc:42',
udp_source_port: 10,
udp_destination_port: 20,
udp_payload: payload).to_binary_s
t.times do
@socket.write(udp)
end
end
end
# iface = RawSocket.new('eth0')
# iface.udp_send
# 各種オプションはコチラを参照ください: https://relishapp.com/trema/pio/docs/udp
@shun159
Copy link
Author

shun159 commented Sep 13, 2016

PF_PACKETでInterfaceをRubyでつかむ方法はコチラから。
https://github.com/trema/phut/blob/develop/lib/phut/raw_socket.rb

@shun159
Copy link
Author

shun159 commented Oct 17, 2016

udp = Udp.new(destination_mac: '01:01:01:01:01:01',
              source_mac: '00:0b:82:01:fc:42',
              udp_source_port: 10,
              udp_destination_port: 20,
              # ここにはbinary(string クラス)のデータを格納してください。
              udp_payload: (1..100).to_a.pack("C*"))

# これで戻せます。
Udp.read(udp.to_binary).udp_payload.unpack("C*")

@shun159
Copy link
Author

shun159 commented Oct 17, 2016

tremaでスイッチから出す場合

class Test < Trema::Controller
  def start(_args)
    @port_no = 1
  end

  def switch_ready(dpid)
    send_packet_out(dpid, raw_data: udp.to_binary, actions: [SendOutPort.new(@port_no)]
  end
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment