如何在bash中存储32位小端有符号整数? [英] How do I store a 32-bit little-endian Signed Integer in bash?

查看:19
本文介绍了如何在bash中存储32位小端有符号整数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(*在下面的帖子中,所有IP、端口和密码都已更改。很抱歉这篇文章的格式,编辑似乎不喜欢换行。)

问题:如何将整数存储为带符号的32位小端?

背景:我正在尝试使用RCon连接到bash中的一台Minworld服务器。到目前为止,服务器显示正在接收连接,但我无法正确格式化数据包。我可以使用mcrcon连接到服务器并在Wireshark中查看数据包,但当我尝试使用bash脚本时,数据包长度、请求ID和类型值看起来不正确。

以下是我的一些来源、疑难解答数据和我的代码,它们可能有助于回答这个问题。

来源:https://wiki.vg/RCON

实现:https://developer.valvesoftware.com/wiki/Source_RCON_Protocol

服务器控制台:

[22:24:09警告]:跟不上!服务器是否超载?运行时间落后3190毫秒或63刻度

[22:24:23信息]:RCON连接来源:/164.256.8.10

[22:24:34警告]:跟不上!服务器是否超载?运行时间落后9961毫秒或199个刻度

[22:24:55警告]:跟不上!服务器是否超载?运行时间落后2006ms或40刻度

[22:25:12信息]:RCON连接来源:/164.256.8.10

Wireshark:(mcrcon数据)

编码:

#!/bin/bash

# Length    int     Length of remainder of packet
# Request ID    int     Client-generated ID
# Type  int     3 for login, 2 to run a command, 0 for a multi-packet response
# Payload   byte[]  ASCII text
# 2-byte pad    byte, byte  Two null bytes 

# Connection details
RCON_HEADER=$(echo -e "xffxffxffxff")
HOST="192.168.0.173"
PORT=12345  
LENGTH=0 # Length of packet
REQUESTID=$RANDOM
PASSWORD="$1"
RES=0
COM=2
AUTH=3
NULL=""
COMMAND=${@:2}
echo "command: $COMMAND"



## Packet Format as per docs
#Packet Size in Bytes
#Request ID any int
#Type as above
#Body null terminated ascii string
#Empty string null terminated

build_packet()
{
    local TYPE="$1";
    $([ "$TYPE" == "$AUTH" ]) && local BODY="$PASSWORD" || local BODY=$COMMAND;
    local DATA="$REQUESTID$TYPE$BODY";    
    local LENGTH=${#DATA};
    local PACKET="$LENGTH$DATA";    
    echo $PACKET;
}



send()
{
    #local PACKET="$1"
    echo "sending: $PACKET"
    printf "$PACKET%s%s" >&5 &
}

read ()
{
    LENGTH="$1"
    RETURN=`dd bs=$1 count=1 <&5 2> /dev/null`
}


echo "trying to open socket"
# try to connect
if ! exec 5<> /dev/tcp/$HOST/$PORT; then
  echo "`basename $0`: unable to connect to $HOST:$PORT"
  exit 1
fi
echo "socket is open"


PACKET=$(build_packet $AUTH $PASSWORD);
echo "Command: $COMMAND"
echo "Packet: $PACKET"

send $PACKET

read 7
echo "RETURN: $RETURN"


PACKET=$(build_packet $COM $COMMAND);
echo "Command: $COMMAND"
echo "Packet: $PACKET"


send $PACKET

read 7
echo "RETURN: $RETURN"

引用编码:https://blog.chris007.de/using-bash-for-network-socket-operation/

推荐答案

解决方案是按如下方式进行十六进制编码和解码:

build_packet()
{
    local TYPE="$1"
    local BODY=""
    $([ "$TYPE" == "$AUTH" ]) && BODY="$PASSWORD" || BODY="$COMMAND"

    # Add null chars "" and hex encode to preserve them "xxd -p".
    # David C Rankin also mentioned, you could possibly printf them in using flags.
    local DATA=`echo -ne "$ID$TYPE$BODY" | xxd -p | tr -d '
'`

    local LEN="${#DATA}"
    LEN=$((LEN / 2))
    LEN="$(asc $LEN)"  
    LEN=`echo -ne "$LEN" | xxd -p | tr -d '
'`
    local PACKET="$LEN$DATA"    
    echo $PACKET
}
注意:#(Asc)是将LEN转换为ASCII字符的自定义函数。我不知道为什么数据包长度必须是ASCII字符,但同样是整数的类型不是。也许其他人可以回答这个问题。

在传输时,十六进制被解码为"ECHO-NE"$Packet"|xxd-r-p>&;5&;"。

这篇关于如何在bash中存储32位小端有符号整数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆