<commit_before>#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8 -*-
################################################################
# Copyright (c) 2016 <NAME> <<EMAIL>>
# 本ツールは Apache License 2.0 ライセンスで公開します。
# 著作権については ./LICENSE もご確認ください
################################################################
# ruby で綴る、簡易で adhoc な、arp と ping の送信ツール
################################################################
# pinger = NwDiy::Pinger.new(ifp, localip)
#    インターフェース ifp に、random な MAC addrを割り当てる
#    インターフェース ifp に、引数で指定された IP addr を割り当てる
#    (ifp はイーサネットインターフェースであること)
# pinger.ping(アドレス)
#    ifp に ARP req, ICMPv4 Echo を送信し、
#    ifp からの ICMPv4 EchoReply を受信する
# pinger.pong
#    ifp で ARP, ICMPv4 に応答する

require_relative '../lib/nwdiy'

require 'nwdiy/interface'
require 'nwdiy/packet/ethernet'
require 'nwdiy/packet/arp'
require 'nwdiy/packet/ip/icmp/echo'

module NwDiy
  class Pinger

    def initialize(ifp, localip)
      @ifp = ifp.kind_of?(NwDiy::Interface) ? ifp : NwDiy::Interface.new(ifp)
      @ifp.local or @ifp.local(NwDiy::Packet::MacAddr.new(:local))
      @localip = localip.kind_of?(IPAddr) ? localip : IPAddr.new(localip, Socket::AF_INET)
    end

    attr_reader :ifp, :localip

    def ping(addr)
      addr.kind_of?(IPAddr) or
        addr = IPAddr.new(addr, Socket::AF_INET)
      req = NwDiy::Packet::Ethernet.new
      req.dst = self.arpResolve(addr)
      req.src = @ifp.local
      req.data = ip = NwDiy::Packet::IPv4.new
      ip.src = @localip
      ip.dst = addr
      ip.data = icmp = NwDiy::Packet::IP::ICMP4.new
      icmp.data = NwDiy::Packet::IP::ICMP::EchoRequest.new
      puts req
      @ifp.send(req)
      loop do
        res = @ifp.recv
        self.forme?(res, req.dst, addr) or
          next
        res.data.is_a?(NwDiy::Packet::IPv4) or
          next
        res.data.data.is_a?(NwDiy::Packet::IP::ICMP4) or
          next
        res.data.data.data.is_a?(NwDiy::Packet::IP::ICMP::EchoReply) or
          next
        unless res.data.cksum_ok?
          puts "BAD CHECKSUM"
          next
        end
        return res
      end
    end

    def arpResolve(addr)
      @mactable and @mactable[addr.to_s] and
        return @mactable[addr.to_s]
      req = NwDiy::Packet::Ethernet.new
      req.dst = NwDiy::Packet::MacAddr.new('ff-ff-ff-ff-ff-ff')
      req.src = @ifp.local
      req.data = arp = NwDiy::Packet::ARP.new
      arp.oper = :request
      arp.sndmac = @ifp.local
      arp.sndip4 = @localip
      arp.tgtip4 = addr
      @ifp.send(req)
      loop do
        res = @ifp.recv
        (res.type == 0x0806) or
          next
        res.data.response? or
          next
        self.forme?(res, nil, addr) or
          next
        @mactable or
          @mactable = Hash.new
        return @mactable[addr.to_s] = res.data.sndmac
      end
    end

    def pong
      loop do
        eth = @ifp.recv
        self.forme?(eth) or
          next

        case eth.type
        when 0x0806
          unless eth.data.request?
            puts "ignore arp.oper = #{eth.data.oper} != EchoRequest"
            next
          end
          eth.dst = eth.src<commit_msg>eth.dst for ARP reply must be from ARP srcmac, not from Ether src.<commit_after>#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8 -*-
################################################################
# Copyright (c) 2016 <NAME> <<EMAIL>>
# 本ツールは Apache License 2.0 ライセンスで公開します。
# 著作権については ./LICENSE もご確認ください
################################################################
# ruby で綴る、簡易で adhoc な、arp と ping の送信ツール
################################################################
# pinger = NwDiy::Pinger.new(ifp, localip)
#    インターフェース ifp に、random な MAC addrを割り当てる
#    インターフェース ifp に、引数で指定された IP addr を割り当てる
#    (ifp はイーサネットインターフェースであること)
# pinger.ping(アドレス)
#    ifp に ARP req, ICMPv4 Echo を送信し、
#    ifp からの ICMPv4 EchoReply を受信する
# pinger.pong
#    ifp で ARP, ICMPv4 に応答する

require_relative '../lib/nwdiy'

require 'nwdiy/interface'
require 'nwdiy/packet/ethernet'
require 'nwdiy/packet/arp'
require 'nwdiy/packet/ip/icmp/echo'

module NwDiy
  class Pinger

    def initialize(ifp, localip)
      @ifp = ifp.kind_of?(NwDiy::Interface) ? ifp : NwDiy::Interface.new(ifp)
      @ifp.local or @ifp.local(NwDiy::Packet::MacAddr.new(:local))
      @localip = localip.kind_of?(IPAddr) ? localip : IPAddr.new(localip, Socket::AF_INET)
    end

    attr_reader :ifp, :localip

    def ping(addr)
      addr.kind_of?(IPAddr) or
        addr = IPAddr.new(addr, Socket::AF_INET)
      req = NwDiy::Packet::Ethernet.new
      req.dst = self.arpResolve(addr)
      req.src = @ifp.local
      req.data = ip = NwDiy::Packet::IPv4.new
      ip.src = @localip
      ip.dst = addr
      ip.data = icmp = NwDiy::Packet::IP::ICMP4.new
      icmp.data = NwDiy::Packet::IP::ICMP::EchoRequest.new
      puts req
      @ifp.send(req)
      loop do
        res = @ifp.recv
        self.forme?(res, req.dst, addr) or
          next
        res.data.is_a?(NwDiy::Packet::IPv4) or
          next
        res.data.data.is_a?(NwDiy::Packet::IP::ICMP4) or
          next
        res.data.data.data.is_a?(NwDiy::Packet::IP::ICMP::EchoReply) or
          next
        unless res.data.cksum_ok?
          puts "BAD CHECKSUM"
          next
        end
        return res
      end
    end

    def arpResolve(addr)
      @mactable and @mactable[addr.to_s] and
        return @mactable[addr.to_s]
      req = NwDiy::Packet::Ethernet.new
      req.dst = NwDiy::Packet::MacAddr.new('ff-ff-ff-ff-ff-ff')
      req.src = @ifp.local
      req.data = arp = NwDiy::Packet::ARP.new
      arp.oper = :request
      arp.sndmac = @ifp.local
      arp.sndip4 = @localip
      arp.tgtip4 = addr
      @ifp.send(req)
      loop do
        res = @ifp.recv
        (res.type == 0x0806) or
          next
        res.data.response? or
          next
        self.forme?(res, nil, addr) or
          next
        @mactable or
          @mactable = Hash.new
        return @mactable[addr.to_s] = res.data.sndmac
      end
    end

    def pong
      loop do
        eth = @ifp.recv
        self.forme?(eth) or
          next

        case eth.type
        when 0x0806
          unless eth.data.request?
            puts "ignore arp.oper = #{eth.data.oper} != EchoRequest"
            next
          end
          eth.dst = eth.data.sndmaceth.src
{'fraction_non_alphanumeric': 0.17752134049952575, 'fraction_numerical': 0.008220044261776794, 'mean_word_length': 2.324750394114556, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2043627', 'n_tokens_mistral': 2542, 'n_tokens_neox': 2472, 'n_words': 465}