73 lines
1.7 KiB
JavaScript
73 lines
1.7 KiB
JavaScript
|
import React from "react"
|
||
|
|
||
|
import { Address4, Address6 } from "ip-address"
|
||
|
|
||
|
const ENDS_WITH_MASK_RE = /\/(((255|254|252|248|240|224|192|128|0)\.){3}(255|254|252|248|240|224|192|128|0))$/
|
||
|
const DEFAULT_IP = '2001:4860:4860::8888/32' // hi, 8.8.8.8
|
||
|
|
||
|
class IPInput extends React.Component {
|
||
|
constructor(props) {
|
||
|
super(props)
|
||
|
const ip = props.ip ? (props.ip.correctForm ? props.ip.correctForm() : props.ip) : DEFAULT_IP
|
||
|
this.state = { text: ip }
|
||
|
|
||
|
this.handleChange = this.handleChange.bind(this)
|
||
|
}
|
||
|
|
||
|
componentDidMount() {
|
||
|
this.setNewIP(this.state.text)
|
||
|
}
|
||
|
|
||
|
handleChange(event) {
|
||
|
this.setState({
|
||
|
text: this.setNewIP(event.target.value),
|
||
|
})
|
||
|
}
|
||
|
|
||
|
setNewIP(realIP) {
|
||
|
let ip = realIP
|
||
|
const ipv4endmask = ENDS_WITH_MASK_RE.exec(ip)
|
||
|
let valid = true
|
||
|
if (ipv4endmask) {
|
||
|
ip = ip.slice(0, ip.length - ipv4endmask[0].length)
|
||
|
const netmaskv4 = new Address4(ipv4endmask[1])
|
||
|
const nmbi = netmaskv4.bigInteger()
|
||
|
const prefixLen = 32 - nmbi.getLowestSetBit()
|
||
|
for (let n = 32 - prefixLen; n < 32 && valid; n++) {
|
||
|
if (!nmbi.testBit(n)) valid = false
|
||
|
}
|
||
|
if (valid)
|
||
|
ip += `/${prefixLen}`
|
||
|
}
|
||
|
|
||
|
let ipv4 = null
|
||
|
try {
|
||
|
ipv4 = new Address4(ip)
|
||
|
} catch (e) { }
|
||
|
|
||
|
let ipv6 = null
|
||
|
try {
|
||
|
ipv6 = new Address6(ip)
|
||
|
} catch (e) { }
|
||
|
|
||
|
valid = valid && (ipv6 || ipv4)
|
||
|
if (valid)
|
||
|
if (ipv6)
|
||
|
this.props.onChange(ipv6)
|
||
|
else
|
||
|
this.props.onChange(ipv4)
|
||
|
else
|
||
|
this.props.onChange(null)
|
||
|
|
||
|
return realIP
|
||
|
}
|
||
|
|
||
|
render() {
|
||
|
return (
|
||
|
<input type="text" value={this.state.text} onChange={this.handleChange}></input>
|
||
|
)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
export default IPInput
|