IPAddr
IPAddr
IPAddr는 IP 주소를 다루기 위한 메서드 모음을 제공하는 클래스예요. IPv4와 IPv6를 모두 지원해요.
출처: Ruby 4.0 API
본문
IP 주소를 문자열로 다루다 보면 자릿수나 축약 표기 때문에 비교·계산이 번거로워져요. IPAddr는 주소를 숫자와 주소 패밀리로 깔끔하게 정규화해서, 마스크를 씌우거나 범위에 포함되는지 확인하는 작업을 쉽게 해 줘요.
require 'ipaddr'
ipaddr1 = IPAddr.new "3ffe:505:2::1"
p ipaddr1 #=> #<IPAddr: IPv6:3ffe:0505:0002:0000:0000:0000:0000:0001/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff>
p ipaddr1.to_s #=> "3ffe:505:2::1"
ipaddr2 = ipaddr1.mask(48) #=> #<IPAddr: IPv6:3ffe:0505:0002:0000:0000:0000:0000:0000/ffff:ffff:ffff:0000:0000:0000:0000:0000>
p ipaddr2.to_s #=> "3ffe:505:2::"
ipaddr3 = IPAddr.new "192.168.2.0/24"
p ipaddr3 #=> #<IPAddr: IPv4:192.168.2.0/255.255.255.0>
inspect 결과를 보면 주소와 마스크가 함께 표시돼요. mask(48)을 호출하면 48비트까지의 네트워크 부분만 남기고 나머지 호스트 부분이 0으로 채워지는 게 보이죠.
상수 (Constants)
IN4MASK— IPv4용 32비트 마스크.IN6FORMAT— IPv6용 포맷 문자열.IN6MASK— IPv6용 128비트 마스크.RE_IPV4ADDRLIKE— IPv4 주소를 파싱하기 위해 내부적으로 쓰는Regexp.RE_IPV6ADDRLIKE_COMPRESSED— IPv6 주소를 파싱하기 위해 내부적으로 쓰는Regexp.RE_IPV6ADDRLIKE_FULL— IPv6 주소를 파싱하기 위해 내부적으로 쓰는Regexp.VERSION— 버전 문자열.
속성 (Attributes)
family[R] — 이 IP 주소의 주소 패밀리(Socket::AF_INET또는Socket::AF_INET6)를 돌려줘요.
클래스 메서드
new(addr = '::', family = Socket::AF_UNSPEC)
사람이 읽을 수 있는 IP 주소 문자열이나, packed in_addr 값과 주소 패밀리로 새 ipaddr 객체를 만들어요.
문자열의 경우 "address", "address/prefixlen", "address/mask" 형태를 인식해요. IPv6 주소는 대괄호([와 ])로 감쌀 수 있어요. prefixlen이나 mask를 지정하면 마스킹된 IP 주소를 돌려줘요. 주소 패밀리는 보통 지정한 문자열로 자동 결정되지만, 두 번째 인자로 명시할 수도 있어요.
IPAddr 클래스는 연산자와 메서드가 많은데, 그중 &, |, include?, == 같은 일부는 IPAddr 객체 대신 문자열이나 packed in_addr 값을 받기도 해요.
new_ntoh(addr)
네트워크 바이트 순서(network byte order)의 문자열로 된 IP 주소를 담은 새 ipaddr를 만들어요.
ntop(addr)
네트워크 바이트 순서 문자열 형태의 IP 주소를 사람이 읽을 수 있는 형태로 바꿔요. 그 문자열은 Encoding::ASCII_8BIT(BINARY)로 인코딩돼 있어야 해요. 4바이트면 IPv4(점분리), 16바이트면 IPv6로 처리하고 그 외엔 AddressFamilyError가 나요.
인스턴스 메서드
&(other)
비트 AND로 만든 새 ipaddr를 돌려줘요.
+(offset)
원래 주소보다 offset만큼 큰 새 ipaddr를 돌려줘요.
-(offset)
원래 주소보다 offset만큼 작은 새 ipaddr를 돌려줘요.
<<(num)
비트 왼쪽 시프트로 만든 새 ipaddr를 돌려줘요.
<=>(other)
ipaddr를 다른 값과 비교해요. 주소 패밀리가 다르면 nil을 돌려줘요.
==(other)
두 ipaddr가 같으면 true를 돌려줘요. 패밀리와 주소 숫자 값이 모두 같아야 해요.
===(other)
include?의 별칭이에요.
>>(num)
비트 오른쪽 시프트로 만든 새 ipaddr를 돌려줘요.
|(other)
비트 OR로 만든 새 ipaddr를 돌려줘요.
~()
비트 부정(negation)으로 만든 새 ipaddr를 돌려줘요.
as_json(*)
IP 주소를 프리픽스와 함께 나타내는 문자열을 돌려줘요. IPv4면 프리픽스가 32, IPv6면 128일 때 to_s를, 그 외에는 cidr 표기를 돌려줘요.
cidr()
CIDR 표기법("주소/prefix")의 문자열을 돌려줘요.
eql?(other)
Hash가 쓰는 동등성 검사예요. 클래스·해시·값이 모두 같아야 true예요.
hash()
Hash, Set, Array가 쓰는 해시 값을 돌려줘요.
hton()
네트워크 바이트 순서 문자열 형태의 IP 주소를 돌려줘요.
include?(other)
주어진 ipaddr가 이 범위 안에 있으면 true를 돌려줘요.
require 'ipaddr'
net1 = IPAddr.new("192.168.2.0/24")
net2 = IPAddr.new("192.168.2.100")
net3 = IPAddr.new("192.168.3.0")
net4 = IPAddr.new("192.168.2.0/16")
p net1.include?(net2) #=> true
p net1.include?(net3) #=> false
p net1.include?(net4) #=> false
p net4.include?(net1) #=> true
192.168.2.100은 /24 네트워크 안에 있으니 포함되고, /16 네트워크가 /24를 포함하는 관계는 확인할 수 있어요.
inspect()
"#<IPAddr: family:address/mask>" 형태의 사람이 읽을 수 있는 표현을 돌려줘요.
ip6_arpa()
RFC 3172와 호환되는 DNS 역방향 조회용 문자열(.ip6.arpa 형태)을 돌려줘요. IPv6 주소가 아니면 InvalidAddressError가 나요.
ip6_int()
RFC 1886과 호환되는 DNS 역방향 조회용 문자열(.ip6.int 형태)을 돌려줘요. IPv6가 아니면 InvalidAddressError가 나요.
ipv4?()
IPv4 주소면 true를 돌려줘요.
ipv4_compat()
네이티브 IPv4 주소를 IPv4-호환(compatible) IPv6 주소로 바꾼 새 ipaddr를 돌려줘요. 구식(obsolete)이라 $VERBOSE가 켜지면 경고가 나요.
ipv4_compat?()
IPv4-호환 IPv6 주소면 true를 돌려줘요. 역시 구식이에요.
ipv4_mapped()
네이티브 IPv4 주소를 IPv4-매핑(mapped) IPv6 주소로 바꾼 새 ipaddr를 돌려줘요.
ipv4_mapped?()
IPv4-매핑 IPv6 주소면 true를 돌려줘요.
ipv6?()
IPv6 주소면 true를 돌려줘요.
link_local?()
링크-로컬(link-local) 주소면 true를 돌려줘요. RFC 3927로 예약된 IPv4 169.254.0.0/16과 RFC 4291로 예약된 링크-로컬 IPv6 유니캐스트 fe80::/10을 링크-로컬로 봐요. IPv4-매핑 IPv6 범위의 링크-로컬 IPv4 주소도 링크-로컬로 봐요.
loopback?()
루프백 주소면 true를 돌려줘요. IPv4-매핑 IPv6 범위의 루프백 IPv4도 루프백으로 봐요.
mask(prefixlen)
주어진 prefixlen/netmask(예: 8, 64, "255.255.255.0" 등)로 IP 주소를 마스킹한 새 ipaddr를 돌려줘요.
native()
IPv6 주소를 네이티브 IPv4 주소로 바꾼 새 ipaddr를 돌려줘요. IPv4-매핑이나 IPv4-호환 IPv6 주소가 아니면 self를 돌려줘요.
netmask()
255.255.0.0 같은 문자열 형태의 넷마스크를 돌려줘요.
prefix()
ipaddr의 프리픽스 길이(비트 수)를 돌려줘요.
prefix=(prefix)
프리픽스 길이(비트)를 설정해요. prefix가 정수가 아니면 InvalidPrefixError가 나요.
private?()
사설(private) 주소면 true를 돌려줘요. RFC 1918로 정의된 IPv4 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16과 RFC 4193으로 정의된 IPv6 ULA fc00::/7을 사설로 봐요. IPv4-매핑 IPv6 범위의 사설 IPv4도 사설로 봐요.
reverse()
DNS 역방향 조회용 문자열을 돌려줘요. IPv4면 .in-addr.arpa 형태, IPv6면 RFC 3172 형태를 돌려줘요.
succ()
ipaddr의 다음 주소(주소에 1을 더한 값)를 돌려줘요.
to_i()
ipaddr의 정수 표현을 돌려줘요.
to_json(*a)
IP 주소 표현을 담은 JSON 문자열을 돌려줘요.
to_range()
네트워크 주소의 Range 객체를 만들어요. 시작 주소부터 끝 주소까지의 IPAddr 범위예요.
to_s()
IP 주소 표현을 담은 문자열을 돌려줘요. 연속된 0을 ::로 축약하는 등 보기 좋은 형태로 만듭니다.
to_string()
정규(canonical) 형태의 IP 주소 표현 문자열을 돌려줘요.
wildcard_mask()
0.0.255.255 같은 문자열 형태의 와일드카드 마스크를 돌려줘요.
zone_id()
IPv6 존(zone) 식별자가 있으면 돌려줘요. IPv6 주소가 아니면 InvalidAddressError가 나요.
zone_id=(zid)
IPv6 존 식별자를 설정해요. nil이나 %로 시작하는 형태만 허용돼요. IPv6가 아니면 InvalidAddressError가 나요.
보호된 인스턴스 메서드
mask!(mask)
현재 넷마스크를 주어진 마스크로 설정해요. 문자열("255.255.255.0" 등)이나 prefixlen 정수를 받아요.
set(addr, *family)
내부에 저장된 주소 @addr를 주어진 addr로 설정해요. addr은 첫 family 멤버(Socket::AF_INET 또는 Socket::AF_INET6)로 검증돼요.