Skip to content

Commit 6aec805

Browse files
committed
in progress
1 parent 013947c commit 6aec805

File tree

2 files changed

+108
-14
lines changed

2 files changed

+108
-14
lines changed

arp.rb

+63-14
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,75 @@
11
require "./ethernet"
22
require "./utils"
3+
require "socket"
4+
5+
ARPHRD_ETHER = 1
6+
ARPOP_REQUEST = 1
7+
ETH_ALEN = 6
8+
ETH_P_ARP = [0x0806].pack("S>").unpack1("S")
9+
ETH_P_IP = 0x0800
10+
ETH_TYPE_NUMBER_ARP = 0x0806
11+
PACKET_BROADCAST = 1
12+
PACKET_HOST = 0
13+
TIMEOUT_TIME = 3
14+
AF_PACKET = 0x11
15+
ETH_P_ALL = [0x0003].pack('S>').unpack('S').first
16+
SIOCGIFINDEX = 0x8933 # bits/ioctls.h
17+
SIOCGIFHWADDR = 0x8927 # linux/sockios.h
318

419
class Arp
20+
# TODO: attr_readerいらないかも
21+
include Utils
522
attr_reader :hardware_type, :protocol_type, :hardware_size, :protocol_size, :opcode, :sender_mac_addr,
623
:sender_ip_addr, :target_mac_addr, :target_ip_addr
7-
def initialize(sender_mac_addr, sender_ip_addr, target_ip_addr)
8-
@hardware_type = 0x0001
9-
@protocol_type = 0x0800
10-
@hardware_size = 0x06
11-
@protocol_size = 0x04
12-
@opcode = 0x0001
13-
@sender_mac_addr = sender_mac_addr
14-
@sender_ip_addr = sender_ip_addr
15-
@target_mac_addr = 0x000000000000
16-
@target_ip_addr = target_ip_addr
24+
def initialize(target_ip_addr)
25+
@hardware_type = [0x0001].pack("S>")
26+
@protocol_type = [0x0800].pack("S>")
27+
@hardware_size = [0x06].pack("C")
28+
@protocol_size = [0x04].pack("C")
29+
@opcode = [0x0001].pack("S>")
30+
@sender_mac_addr = get_packed_local_mac_addr
31+
@sender_ip_addr = get_packed_local_ip_addr
32+
@target_mac_addr = [0].pack("C") * 6
33+
@target_ip_addr = target_ip_addr.split(".").map(&:to_i).pack("C*")
34+
end
35+
36+
def sum_data_without_address
37+
@hardware_type + @protocol_type + @hardware_size + @protocol_size + @opcode
38+
end
39+
40+
def sum_address
41+
sum_data_without_address + @sender_mac_addr + @sender_ip_addr + @target_mac_addr + @target_ip_addr
42+
end
43+
44+
def bind_if(socket, interface)
45+
# Get the system's internal interface index value
46+
ifreq = [ interface, '' ].pack('a16a16')
47+
socket.ioctl(SIOCGIFINDEX, ifreq)
48+
index_str = ifreq[16, 4]
49+
50+
# Build our sockaddr_ll struct so we can bind to this interface. The struct
51+
# is defined in linux/if_packet.h and requires the interface index.
52+
eth_p_all_hbo = [ ETH_P_ALL ].pack('S').unpack('S>').first
53+
sll = [ Socket::AF_PACKET, eth_p_all_hbo, index_str ].pack('SS>a16')
54+
socket.bind(sll)
1755
end
1856

1957
def send
20-
utils = Utils.new
21-
Ethernet.new("ARP", utils.get_local_mac_and_ip_addr.mac_addr, "ff:ff:ff:ff:ff:ff")
58+
type = [0x0806].pack("S>")
59+
src_mac_addr = get_packed_local_mac_addr
60+
dst_mac_addr = [255].pack("C") * 6
61+
header = Ethernet.new(type, src_mac_addr, dst_mac_addr).header
62+
data = sum_data_without_address + sum_address
63+
request = header + data
64+
s = Socket.new(AF_PACKET, Socket::SOCK_RAW, ETH_P_ALL)
65+
# ARPはUDP通信でもTCP通信でもない?
66+
# client_socket_addr = Socket.pack_sockaddr_in(8863, Socket.gethostname)
67+
# s.bind(client_socket_addr)
68+
# bind_if(s)
69+
bind_if(s, "en0")
70+
res = s.send(request, 0)
71+
p res
2272
end
2373
end
2474

25-
a = Arp.new(1, 1, 1)
26-
p a
75+
Arp.new("10.14.69.254").send

ping.rb

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
require "socket"
2+
3+
class Ping
4+
ICMP_ECHOREPLY = 0 # Echo reply
5+
ICMP_ECHO = 8 # Echo request
6+
ICMP_SUBCODE = 0
7+
AF_PACKET = 0x11
8+
TYPE_ICMP_ECHO_REQUEST = 0x08
9+
10+
# def initialize
11+
# @seq = 0
12+
# @bind_port = 0
13+
# @bind_host = nil
14+
# @data_size = 56
15+
# @data = ''
16+
17+
# 0.upto(@data_size){ |n| @data << (n % 256).chr }
18+
19+
# @ping_id = (Thread.current.object_id ^ Process.pid) & 0xffff
20+
# end
21+
22+
# def to_trans_data()
23+
# bynary_data =
24+
# @type.to_s(2).rjust(8, "0") +
25+
# @code.to_s(2).rjust(8, "0") +
26+
# checksum.to_s(2).rjust(16, "0") +
27+
# @id.to_s(2).rjust(16, "0") +
28+
# @seq_number.to_s(2).rjust(16, "0")
29+
30+
# data_byte_arr = bynary_data.scan(/.{1,8}/)
31+
# data_byte_arr.map! { |byte| byte.to_i(2).chr } # TO ASCII
32+
# data_byte_arr.join + @data
33+
# end
34+
35+
def ping
36+
socket = Socket.new(Socket::AF_INET, Socket::SOCK_RAW, Socket::IPPROTO_ICMP)
37+
38+
socket.connect(Socket.pack_sockaddr_in(0, "8.8.8.8"))
39+
40+
socket.send("hoge", 0)
41+
end
42+
end
43+
44+
pinger = Ping.new
45+
pinger.ping

0 commit comments

Comments
 (0)