📄 natpmpdeviceimpl.java
字号:
nat_pmp_found = true;
return true;
}catch( PortUnreachableException e ){
return( false );
}
}
/**
* Asks for a public port to be mapped to a private port from this host.
*
* NAP-PMP allows the device to assign another public port if the
* requested one is taken. So, you should check the returned port.
*
* @param tcp true TCP, false UDP
* @return the returned publicPort. -1 if error occured
* @todo either take a class (like UPnPMapping) or return a class
**/
public int addPortMapping( boolean tcp, int publicPort,
int privatePort ) throws Exception {
// check for actual connection!
return portMappingProtocol( tcp, publicPort, privatePort,
NATMAP_DEFAULT_LEASE );
}
/**
* Delete a mapped public port
*
* @param tcp true TCP, false UDP port
* @param publicPort the public port to close
* @param privatePort the private port that it is mapped to
* @warn untested
*/
public void deletePortMapping( boolean tcp, int publicPort,
int privatePort )
throws Exception {
/**
* if the request was successful, a zero lifetime will
* delete the mapping and return a public port of 0
**/
// check for actual connection
int result = portMappingProtocol(tcp, publicPort, privatePort, 0);
}
/**
* General port mapping protocol
*
*
*
**/
public int portMappingProtocol( boolean tcp, int publicPort,
int privatePort, int lifetime )
throws Exception {
byte NATOp = (tcp?NATOp_MapTCP:NATOp_MapUDP);
// Should check for errors - only using lower 2 bytes
byte pubPort[] = intToByteArray(publicPort);
byte priPort[] = intToByteArray(privatePort);
byte portLifeTime[] = intToByteArray(lifetime);
// Generate Port Map request packet
byte dstBuf[] = new byte[NATPortMapRequestLen];
dstBuf[0] = NATMAP_VER; // Ver
dstBuf[1] = NATOp; // OP
dstBuf[2] = 0; // Reserved - 2 bytes
dstBuf[3] = 0;
dstBuf[4] = priPort[2]; // Private Port - 2 bytes
dstBuf[5] = priPort[3];
dstBuf[6] = pubPort[2]; // Requested Public Port - 2 bytes
dstBuf[7] = pubPort[3];
for (int i = 0; i < 4; i++) {
dstBuf[8 + i] = portLifeTime[i];
}
DatagramPacket dstPkt = new DatagramPacket(dstBuf, dstBuf.length);
byte recBuf[] = new byte[NATPortMapReplyLen];
DatagramPacket recPkt = sendNATMsg(natPriInet, dstPkt, recBuf);
// Unpack this and check codes
int recVers = unsigned8ByteArrayToInt( recBuf, 0 );
int recOP = unsigned8ByteArrayToInt( recBuf, 1 );
int recCode = unsigned16ByteArrayToInt( recBuf, 2 );
int recEpoch = unsigned32ByteArrayToInt( recBuf, 4);
int recPriPort = unsigned16ByteArrayToInt( recBuf, 8 );
int recPubPort = unsigned16ByteArrayToInt( recBuf, 10 );
int recLifetime = unsigned32ByteArrayToInt( recBuf, 12);
/**
* Should save the epoch. This can be used to determine the
* time the mapping will be deleted.
**/
log("Seconds since Start of Epoch: " + recEpoch);
log("Returned Mapped Port Lifetime: " + recLifetime);
if ( recCode != 0 )
throw( new Exception( "An error occured while getting a port mapping: " + recCode ) );
if ( recOP != ( NATOp + 128) )
throw( new Exception( "Received the incorrect port type: " + recOP) );
if ( lifetime != recLifetime )
log("Received different port life time!");
return recPubPort;
}
public InetAddress
getLocalAddress()
{
return( hostInet );
}
public NetworkInterface
getNetworkInterface()
{
return( networkInterface );
}
public String
getExternalIPAddress()
{
return( natPubInet.getHostAddress());
}
public int
getEpoch()
{
return( nat_epoch );
}
protected void
log(
String str )
{
adapter.log( str );
}
/**
*
* Bunch of conversion functions
*
**/
/**
* Convert the byte array containing 32-bit to an int starting from
* the given offset.
*
* @param b The byte array
* @param offset The array offset
* @return The integer
*/
public static int unsigned32ByteArrayToInt(byte[] b, int offset) {
int value = 0;
for (int i = 0; i < 4; i++) {
int shift = (4 - 1 - i) * 8;
value += ( (int) b[i + offset] & 0xFF) << shift;
}
return value;
}
/**
* Convert the byte array containing 16-bits to an int starting from
* the given offset.
*
* @param b The byte array
* @param offset The array offset
* @return The integer
*/
public static int unsigned16ByteArrayToInt(byte[] b, int offset) {
int value = 0;
for (int i = 0; i < 2; i++) {
int shift = (2 - 1 - i) * 8;
value += ( (int) b[i + offset] & 0xFF) << shift;
}
return value;
}
/**
* Convert the byte array containing 8-bits to an int starting from
* the given offset.
*
* @param b The byte array
* @param offset The array offset
* @return The integer
*/
public static int unsigned8ByteArrayToInt(byte[] b, int offset) {
return (int) b[offset] & 0xFF;
}
public short unsignedByteArrayToShort(byte[] buf) {
if (buf.length == 2) {
int i;
i = ( ( ( (int) buf[0] & 0xFF) << 8) | ( (int) buf[1] & 0xFF) );
return (short) i;
}
return -1;
}
/**
* Convert a 16-bit short into a 2 byte array
*
* @return unsigned byte array
**/
public byte[] shortToByteArray(short v) {
byte b[] = new byte[2];
b[0] = (byte) ( 0xFF & (v >> 8) );
b[1] = (byte) ( 0xFF & (v >> 0) );
return b;
}
/**
* Convert a 32-bit int into a 4 byte array
*
* @return unsigned byte array
**/
public byte[] intToByteArray(int v) {
byte b[] = new byte[4];
int i, shift;
for(i = 0, shift = 24; i < 4; i++, shift -= 8)
b[i] = (byte)(0xFF & (v >> shift));
return b;
}
public String intArrayString(int[] buf) {
StringBuffer sb = new StringBuffer();
for(int i = 0; i < buf.length; i++) {
sb.append(buf[i]).append(" ");
}
return sb.toString();
}
public String byteArrayString(byte[] buf) {
StringBuffer sb = new StringBuffer();
for(int i = 0; i < buf.length; i++) {
sb.append(buf[i]).append(" ");
}
return sb.toString();
}
/**
*
* @param init takes the host address
* @return String the address as (xxx.xxx.xxx.1)
**/
private String convertHost2RouterAddress(InetAddress inet) {
byte rawIP[] = inet.getAddress();
// assume router is at xxx.xxx.xxx.1
rawIP[3] = 1;
// is there no printf in java?
String newIP = (rawIP[0]&0xff) +"."+(rawIP[1]&0xff)+"."+(rawIP[2]&0xff)+"."+(rawIP[3]&0xff);
return newIP;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -