自定义命令备录

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<signal.h>
#include<errno.h>
#include<sys/time.h>

#define BUF_LEN 16
#define OPTION_STRING "i:p:n:v:w:r:c:l:h:a:d:b:q:z"
#define SET0_BIT(value, bit) ((value)&=~(1<<(bit)))
#define SET1_BIT(value, bit) ((value)|= (1<<(bit)))
#define GET_BIT(value, bit) ((value)&(1<<(bit)))
#define CPL_BIT(value, bit) ((value)^=(1<<(bit)))

static int sock_fd = -1;
extern char **environ;
static char *smp_sys_argv_last = NULL;
static char *smp_sys_env_last = NULL;

struct par_val {
    /*clean write read*/
    char mode;
    /*latency switch*/
    char lat_sw;
    /*latency value*/
    char lat_val;
    /*loss packet switch*/
    char packet_loss_sw;
    /*loss packet rate value*/
    char packet_loss_rate;
    char read_loss_val;
    short int read_curr_03_loss_rate_num;
    short int read_curr_1_loss_rate_num;
    short int read_curr_2_loss_rate_num;
    short int read_curr_5_loss_rate_num;
    short int read_curr_10_loss_rate_num;
};

static void
sigint(int signal_num)
{
    if(sock_fd > 0) {
        close(sock_fd);
    }
    exit(-1);
}

static void
udp_send(int fd, int packet_num,
    struct sockaddr *dst, struct par_val val)
{
    int index, ret, flag;
    socklen_t len = sizeof(*dst);
    flag = val.mode;
    char send_buf[BUF_LEN];
    char recv_buf[BUF_LEN];
    memset(send_buf, 0, BUF_LEN);
    memcpy(send_buf, &val, sizeof(val));
    for(index = 0; index < packet_num; index++) {
        ret = sendto(fd, send_buf, sizeof(send_buf), 0, dst, len);
        if(ret < 0) {
            fprintf(stderr, "send error\n");
            if(fd > 0)
                close(fd);
            exit(-1);
        }
        if(flag == 2) {
            printf("--------------------receive data--------------------\n");
            ret = recvfrom(fd, recv_buf, sizeof(recv_buf), 0, dst, &len);
            if(ret > 0) {
                struct par_val recv_val;
                memcpy(&recv_val, recv_buf, sizeof(recv_buf));
                fprintf(stdout, "               current latency value = %d                 \n", (recv_val.read_loss_val - 48));
                switch (val.packet_loss_rate) {
                    case 1:
                        fprintf(stdout, "               current loss packet rate is %%0.3             \n");
                        fprintf(stdout, "               current loss packet num = %d                  \n", recv_val.read_curr_03_loss_rate_num);
                        break;
                    case 10:
                        fprintf(stdout, "               current loss packet rate is %%10               \n");
                        fprintf(stdout, "               current loss packet num = %d                   \n", recv_val.read_curr_1_loss_rate_num);
                        break;
                    case 20:
                        fprintf(stdout, "               current loss packet rate is %%20               \n");
                        fprintf(stdout, "               current loss packet num = %d                   \n", recv_val.read_curr_2_loss_rate_num);
                        break;
                    case 50:
                        fprintf(stdout, "               current loss packet rate is %%50               \n");
                        fprintf(stdout, "               current loss packet num = %d                   \n", recv_val.read_curr_5_loss_rate_num);
                        break;
                    case 100:
                        fprintf(stdout, "               current loss packet rate is %%100               \n");
                        fprintf(stdout, "               current loss packet num = %d                    \n", recv_val.read_curr_10_loss_rate_num);
                        break;
                    default:
                        fprintf(stdout, "--------------------loss packet rate set error--------------------\n");
                        break;
                }
            } else {
                fprintf(stdout, "--------------------recvive data error--------------------\n");
                continue;
            }
        }
    sleep(1);
    }
}

static void
usage(void)
{
    fprintf(stdout, "Usage:\n");
    fprintf(stdout, "Option:\n");
    fprintf(stdout, "        -i, --<server ip>        \n");
    fprintf(stdout, "        -p, --<server port>      \n");
    fprintf(stdout, "        -n, --<packet num>       \n");
    fprintf(stdout, "        -c, --<clean 0>          \n"); 
    fprintf(stdout, "        -w, --<write 1>          \n");
    fprintf(stdout, "        -r, --<read 2>           \n");
    fprintf(stdout, "        -d, --<latency switch>   \n");
    fprintf(stdout, "        -v, --<latency value -- 1:on, 0:off>\n");
    fprintf(stdout, "        -l, --<loss packet switch>\n");
    fprintf(stdout, "        -a, --<loss packet value -- 1:on, 0:off>\n");
    fprintf(stdout, "        byte(1) value, 0:clean, 1:write, 2:read                   \n");
    fprintf(stdout, "        byte(2) value, 0:latency off, 1:latency on                \n");
    fprintf(stdout, "        byte(3) value, latency value,   1 <= value <= 10          \n");
    fprintf(stdout, "        byte(4) value, 0:loss packet off, 1:loss packet on        \n");
    fprintf(stdout, "        byte(5) value, loss packet value, support parameter 1, 10, 20, 50, 100\n");
    fprintf(stdout, "        byte(6) value,   read current latency value\n");
    fprintf(stdout, "        byte(7)-byte(8)  read current 0.3%% loss packet, loss packet number    \n");
    fprintf(stdout, "        byte(9)-byte(10) read current 1%%   loss packet, loss packet number    \n");
    fprintf(stdout, "        byte(11)-byte(12)read current 2%%   loss packet, loss packet number    \n");
    fprintf(stdout, "        byte(13)-byte(14)read current 5%%   loss packet, loss packet number    \n");
    fprintf(stdout, "        byte(15)-byte(16)read current 10%%  loss packet, loss packet number    \n");
    return;
}

static u_char *
smp_strcpyn(u_char *dst, const u_char *src, size_t n)
{
    if (n == 0)
        return dst;
    while (n--) {
        *dst = *src;
        if (*dst == '\0')
            return dst;
        dst++;
        src++;
    }
    *dst = '\0';
    return dst;
}

static int
smp_init_set_proc_title(int argc, char **argv)
{
    int i = 0;
    smp_sys_argv_last = argv[0];

    for(i = 0; i < argc; i++) {
        if (smp_sys_argv_last == argv[i]) {
            smp_sys_argv_last = argv[i] + strlen(argv[i]) + 1;
        }
    }

    smp_sys_env_last = smp_sys_argv_last;

    for (i = 0; environ[i]; i++) {
        if (smp_sys_env_last == environ[i]) {
            smp_sys_env_last = environ[i] + strlen(environ[i]) + 1;
        }
    }

    smp_sys_env_last--;
    return 0;
}

static int
smp_cpy_environs(void)
{
    u_char *new_addr = NULL;
    size_t envsize = smp_sys_env_last - environ[0];

    if ((new_addr = malloc(envsize)) == NULL)
        return -1;
    else {
        u_char *current = new_addr;
        u_char *p = current;
        int i = 0;

        for (i = 0; environ[i]; i++) {
            current = smp_strcpyn(current, (u_char *) environ[i], strlen(environ[i]));
            environ[i] = (char *)p;
            current++;
            p = current;
        }
    }
    return 0;
}

static int
smp_reset_proc_titel(const u_char *title, size_t tlen, int argc, char **argv)
{
    u_char *params = NULL;

    if (argc <= 1) {
        memset(argv[0], '\0', smp_sys_env_last - argv[0]);
        memcpy(argv[0], title, tlen);
        return 0;
    } else {
        u_char *current = NULL;
        u_char *p = NULL;
        size_t size = smp_sys_argv_last - argv[1];
        int i = 0;

        if ((params = malloc(size)) == NULL)
            return 0;
        current = params;
        p = current;

        for (i = 1; i < argc; i++) {
            current = smp_strcpyn(current, (u_char *)argv[i], strlen(argv[i]));
            argv[i] = (char *) p;
            current++;
            p = current;
        }
        memset(argv[0], '\0', smp_sys_env_last - argv[0]);
        current = smp_strcpyn((u_char *)argv[0], title, tlen);
        current++;
        p = current;
        for (i = 1; i < argc; i++) {
            current = smp_strcpyn(current, (const u_char *)argv[i], strlen(argv[i]));
            argv[i] = (char *)p;
            current++;
            p = current;
        }
    }
    return 0;
}

static int
smp_set_proc_titel(const char *title, int argc, char **argv)
{
    size_t tlen = 0;
    if (title == NULL)
        return -1;

    tlen = strlen(title);
    if (tlen <= strlen(argv[0])) {
        for(int index = 0; index < argc; index++) {
            memset(argv[index], '\0', strlen(argv[index]));
        }
        //memset(argv[0], '\0', strlen(argv[0]));
        memcpy(argv[0], title, tlen);
        return 0;
    }

    smp_init_set_proc_title(argc, argv);
    smp_cpy_environs();
    smp_reset_proc_titel((u_char *) title, tlen, argc, argv);
    return 0;
}

int main(int argc, char **argv)
{
    int argflag, packet_num = 1;
    int latency, latency_val;
    int loss_sw, loss_val, mode;
    struct sockaddr_in cli_addr;
    char *ser_ip = "127.0.0.1";
    int ser_port = 8888;
    struct sockaddr_in ser_addr;
    struct par_val val;
    /*Signal callback function*/
    signal(SIGINT, sigint);
    if(argc > 1) {
        if(!strcmp(argv[1], "-s")) {
            if(daemon(0, 0) == -1) {
                fprintf(stdout, "daemon error\n");
                exit(-1);
            }
        } else if(!strcmp(argv[1], "-h")) {
            usage();
            return 0;
        }
    }

    sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
    if(sock_fd < 0) {
        fprintf(stdout, "sock_fd open fail, ^^^^^^^^^^exit^^^^^^^^^^\n");
        return -1;
    }

    memset(&ser_addr, 0, sizeof(ser_addr));
    memset(&cli_addr, 0, sizeof(cli_addr));
    memset(&val, 0, sizeof(val));
    ser_addr.sin_family = AF_INET;
    ser_addr.sin_addr.s_addr = inet_addr(ser_ip);
    //ser_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    ser_addr.sin_port = htons(ser_port);

    while((argflag = getopt(argc, (char **)argv, OPTION_STRING)) != -1) {
        switch (argflag) {
        case 'i':
                ser_ip = optarg;
                ser_addr.sin_addr.s_addr = inet_addr(ser_ip);
                break;
        case 'p':
                ser_port = atoi(optarg);
                ser_addr.sin_port = htons(ser_port);
                break;
        case 'n':
                packet_num = atoi(optarg);
                break;
        case 'c':
                mode = atoi(optarg);
                if(mode != 0) {
                    fprintf(stdout, "clean mode value set error\n");
                    goto failed;
                }
                memset(&val.mode, 0, sizeof(val.mode));
                break;
        case 'w':
                mode = atoi(optarg);
                if(mode != 1) {
                    fprintf(stdout, "write mode value set error\n");
                    goto failed;
                }
                SET1_BIT(val.mode, 0);
                break;
        case 'r':
                mode = atoi(optarg);
                if(mode != 2) {
                    fprintf(stdout, "read mode value set error\n");
                    goto failed;
                }
                SET1_BIT(val.mode, 1);
                break;
        case 'd':
                latency = atoi(optarg);
                if(latency == 0) {
                    memset(&val.lat_sw, 0, sizeof(val.lat_sw));
                } else if(latency == 1) {
                    SET1_BIT(val.lat_sw, 0);
                } else {
                    fprintf(stdout, "latency set error\n");
                    goto failed;
                }
                break;
        case 'v':
                latency_val = atoi(optarg);
                if (latency_val == 1) {
                    SET1_BIT(val.lat_val, 0);
                } else if(latency_val == 2) {
                    SET1_BIT(val.lat_val, 1);
                } else if(latency_val == 3) {
                    SET1_BIT(val.lat_val, 0);
                    SET1_BIT(val.lat_val, 1);
                } else if(latency_val == 4) {
                    SET1_BIT(val.lat_val, 2);
                } else if(latency_val == 5) {
                    SET1_BIT(val.lat_val, 0);
                    SET1_BIT(val.lat_val, 2);
                } else if(latency_val == 6) {
                    SET1_BIT(val.lat_val, 1);
                    SET1_BIT(val.lat_val, 2);
                } else if(latency_val == 7) {
                    SET1_BIT(val.lat_val, 0);
                    SET1_BIT(val.lat_val, 1);
                    SET1_BIT(val.lat_val, 2);
                } else if(latency_val == 8) {
                    SET1_BIT(val.lat_val, 3);
                } else if(latency_val == 9) {
                    SET1_BIT(val.lat_val, 0);
                    SET1_BIT(val.lat_val, 3);
                } else if(latency_val == 10) {
                    SET1_BIT(val.lat_val, 1);
                    SET1_BIT(val.lat_val, 3);
                } else {
                   fprintf(stdout, "lat_val error\n");
                   goto failed;
                }
                break;
        case 'l':
                loss_sw = atoi(optarg);
                if(loss_sw == 0) {
                    memset(&val.packet_loss_sw, 0, sizeof(val.packet_loss_sw));
                } else if(loss_sw == 1) {
                    SET1_BIT(val.packet_loss_sw, 0);
                } else {
                    fprintf(stdout, "loss switch set error\n");
                    goto failed;
                }
                break;
        case 'a':
               loss_val = atoi(optarg);
               if(loss_val == 1) {
                   SET1_BIT(val.packet_loss_rate, 0);
               } else if(loss_val == 10) {
                   SET1_BIT(val.packet_loss_rate, 1);
                   SET1_BIT(val.packet_loss_rate, 3);
               } else if(loss_val == 20) {
                   SET1_BIT(val.packet_loss_rate, 2);
                   SET1_BIT(val.packet_loss_rate, 4);
               } else if(loss_val == 50) {
                   SET1_BIT(val.packet_loss_rate, 1);
                   SET1_BIT(val.packet_loss_rate, 4);
                   SET1_BIT(val.packet_loss_rate, 5);
               } else if(loss_val == 100) {
                   SET1_BIT(val.packet_loss_rate, 2);
                   SET1_BIT(val.packet_loss_rate, 6);
                   SET1_BIT(val.packet_loss_rate, 7);
               } else {
                   fprintf(stdout, "loss value error\n");
                   goto failed;
               }
               break;
        default:
               break;
        }
    }

    fprintf(stdout, "        ip: %s         \n", ser_ip);
    fprintf(stdout, "        port: %d       \n", ser_port);
    fprintf(stdout, "        packet number %d       \n", packet_num);
    smp_set_proc_titel("lt-rdmatest", argc, argv);
    udp_send(sock_fd, packet_num, (struct sockaddr *)&ser_addr, val);
    close(sock_fd);
    return 0;

failed:
    usage();
    close(sock_fd);
    return -1;
}
.PHONY:clean

CFLAGS := -Wall -g
LDLIBS := -lpthread

APPS:= udp_send

all:${APPS}

install:
	sudo mv ${APPS} /usr/bin
clean:
	rm -rf ${APPS}

在这里插入图片描述
在这里插入图片描述
往一个ip发UDP的包,通过命令行配置参数,在data区域填充不同的参数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值