【Linux 应用】通过网络下发配置配置

环境:添加后门可以配置请求地址。后门通过监听按键的方式来启动,监听到一定的后门即可启动一个网络服务线程来等待客户端链接。客户端使用的是网页请求的方式,直接使用get的方式。本文重点在后门网络配置服务端写法。


一、方案很简单,具体不累述:

1、开启服务端。等待客户端响应

2、在网页输入get请求

3、服务端收到请求,并执行操作。

二、服务端代码

#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
#include <unistd.h>
#include <arpa/inet.h>  
#include <netinet/in.h> 

#define PORT    12306   //定义通信端口  
#define BACKLOG 5       //定义侦听队列长度  
#define buflen  1024  
#define OK_CLINET  "HTTP/1.1 200 OK\r\nContent-Length: 17\r\n\r\n{activeResp: 200}"
#define ERR_CLINET "HTTP/1.1 404 Not Found\r\nContent-type error text/html\r\n\r\n"
typedef struct{
    char acKey[32];
    char acValue[64];
}MSG_PARSE_t;

static LRESULT CALLBACK BackDoorDialog (HCSWND hWnd, WPARAM wParam, LPARAM lParam)
{
    LRESULT iRet = 0;
    int nBoxRet = 0;
    char strTmp[32] = {0},strMsg[256] = {0};
    char swstrTmp[32] = {0},swstrMsg[256] = {0};
    int ret = -1;
    pthread_t id;
    
    if(backdoor_id != 0){
        return -1;
    }
    ret = pthread_create(&id, NULL, HttpServer, (void *)NULL);
    if(ret != 0){
        printf("pthread create error \n");
        return -1;
    }
    backdoor_id = id;
    pthread_detach(id);

    if(backdoor_id > 0){
        ret = pthread_kill(backdoor_id , 0);
        if(ret == ESRCH){
            printf("CSPlayService_GetBackList : the specified thread did not exists or already quit\n");
        }else if(ret == EINVAL){
            printf("CSPlayService_GetBackList : signal is invalid\n");
        }else{
            printf("CSPlayService_GetBackList : the specified thread is alive\n");
            pthread_cancel(backdoor_id);
            backdoor_id = 0;
        }
        GUI_DEBUG("pthread_kill backdoor_id !\n");
    }

    return iRet;
}


int StringParseToKeyValueArray( char *pcOriginMsg, 
                         MSG_PARSE_t *psItems,
                         int nItemCunt)
{
    char *pSaveOuter;
    char *pSaveInner;
    char *token;
    char *key;
    char *value;
    char *pstart;
    int i = 0;
    const int BUFSIZE = 1024*10; 
    char *pcDumpMsg=NULL;

    if( NULL == pcOriginMsg ||  NULL == psItems )
    {
        return -1;
    }
    pcDumpMsg =(char *)malloc(BUFSIZE);
    if(pcDumpMsg == NULL)
    {
        return -1;
    }
    if(strlen(pcOriginMsg)<BUFSIZE)
    {
        strncpy(pcDumpMsg, pcOriginMsg, strlen(pcOriginMsg));
    }
    else
    {
        strncpy(pcDumpMsg, pcOriginMsg, BUFSIZE);
    }
    pstart = pcDumpMsg;
    while( NULL != (token = strtok_r(pstart, "&", &pSaveOuter)) && i < nItemCunt)
    {
        pstart = token;
        //key
        if( NULL == (key = strtok_r(pstart, "=", &pSaveInner)))
        {
            free(pcDumpMsg);
            return -1;
        }
        strcpy(psItems[i].acKey, key);

        //value
        if( NULL == (value = strtok_r(NULL, "=", &pSaveInner)))
        {
        }
        else
        {
            strcpy(psItems[i].acValue, value);
        }
        pstart = NULL;
        i++;
    }

    free(pcDumpMsg);
    pcDumpMsg=NULL;
    return i;
}


static int HttpServer()
{
    struct sockaddr_in server_addr; //存储服务器端socket地址结构  
    struct sockaddr_in client_addr; //存储客户端 socket地址结构 
    int sockfd,newfd;
    char readbuf[1024];
    fd_set fds;
    int maxfd;
    int PARSE_PARAM_MAX = 250;
    MSG_PARSE_t stMsgArray[PARSE_PARAM_MAX];
    const char *GET_SETCFG = "GET /setinfo?";
    const int LEN_SETCFG = strlen(GET_SETCFG);

    int ret = -1;    //返回值
  
    sockfd = socket(AF_INET, SOCK_STREAM, 0); //建立一个序列化的,可靠的,双向连接的的字节流  
    if (sockfd<0)  
    {  
        printf("server : server socket create error\n");  
        return -1;  
    }
    
    //初始化地址结构  
    memset(&server_addr, 0, sizeof(server_addr));  
    server_addr.sin_family = AF_INET;           //协议族  
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);   //本地地址  
    server_addr.sin_port = htons(PORT);  
  
    ret = bind(sockfd,(struct sockaddr *)&server_addr,sizeof(server_addr));  
    if (ret < 0)  
    {  
        printf("server : bind error\n");  
        return -1;  
    }  

    ret = listen(sockfd, BACKLOG);   //设置监听的队列大小  
    if (ret < 0)  
    {  
        printf("server : listen error\n");  
        return -1;  
    }
    for (;;)  
    {  
        FD_ZERO(&fds);    
        FD_SET(sockfd, &fds);
        maxfd = sockfd + 1;
        printf("\n\nserver : accept \n\n");
        if( (ret = select(maxfd + 1, &fds, NULL, NULL, NULL)) < 0)
        {
            GUI_DEBUG("select fail\n");
            return;
        }
        if(!FD_ISSET(sockfd, &fds))
        {
            continue;
        }
        
        socklen_t addrlen = sizeof(client_addr);
        memset(readbuf, 0,strlen(readbuf));
        memset(stMsgArray, 0,strlen(stMsgArray));
        //accept返回客户端套接字描述符  
        newfd = accept(sockfd, (struct sockaddr *)&client_addr, &addrlen);  //注,此处为了获取返回值使用 指针做参数  
        if(newfd < 0)  //出错  
        {
            write(newfd, ERR_CLINET, strlen(ERR_CLINET));
            continue;   //结束此次循环
        }
        printf("server : connected\n");
        ret = recv(newfd, readbuf, 1024-1, 0);
        if(ret <= 0) 
        {
            GUI_DEBUG("receive fail\n"); 
            write(newfd, ERR_CLINET, strlen(ERR_CLINET));
            close(newfd);
            continue;
        }
        
        write(newfd, OK_CLINET, strlen(OK_CLINET));
        printf("readbuf = %s", readbuf);
        
        //请求格式为 GET /xxxx?xxxx  HTTP/1.1,去除末尾的 HTTP/1.1
        char *space1 = strstr(readbuf, " HTTP/1");
        if(space1) *space1 = '\0';
        
        GUI_DEBUG("readbuf = %s", readbuf);
        //http://172.30.15.56:12306/setinfo?tang=tang
        if(!strncmp(readbuf, GET_SETCFG, LEN_SETCFG))
        {
            GUI_DEBUG("action = %s %d", readbuf, LEN_SETCFG);
            //char *action = readbuf[LEN_SETCFG -1];
            GUI_DEBUG("action = %s", readbuf+LEN_SETCFG);
            int count = StringParseToKeyValueArray(readbuf+LEN_SETCFG, stMsgArray, PARSE_PARAM_MAX);
            for(int i = 0; i<count;i++){
                printf("acKey = %s", stMsgArray[i].acKey);
                printf("acValue = %s", stMsgArray[i].acValue);
                if(!strncmp(stMsgArray[i].acKey, "ChListAddr", strlen("ChListAddr"))){
                    setChListAddr(stMsgArray[i].acValue);
                    printf("set ChListAddr ok");
                }
                if(!strncmp(stMsgArray[i].acKey, "ChTypeAddr", strlen("ChTypeAddr"))){
                    setChTypeAddr(stMsgArray[i].acValue);
                    printf("set ChTypeAddr ok");
                }
            }
            
        }
        
        close(newfd);
    }  

    //never run here
    printf("http thread error\n");
    close(sockfd);
    return -1;
}

三、客户端请求

http://172.30.15.56:12306/setinfo?tang=tang&sdk=102152&ChListAddr=192.168.15.43:8088&tangtang=tang

四、总结

就不总结了,很简单。有问题留言给我

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值