运行 带参数的程序 C

Run program with parameters C

我需要帮助如何制作带有参数的程序 运行。我需要它 运行 比如:./name_of_program parameter1 parameter2 我需要它来设置 data[] table.

中的参数
    #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <linux/if_packet.h>
#include <linux/if_ether.h>
#include <linux/if_arp.h>
#include <sys/ioctl.h>

#define INTERFACE   "eth0"

int main(int argc, char *argv[]) {
    puts("Wysłanie ramki przez NIC");

    int s_out; /*deskryptor gniazda*/
    int j;

    void* buffer = (void*)malloc(ETH_FRAME_LEN);

    unsigned char* etherhead = buffer;
    unsigned char* data = buffer + 14;

    struct ethhdr *eh = (struct ethhdr *)etherhead;
    struct sockaddr_ll socket_address;
    int send_result = 0;
    struct ifreq ifr;
    int ifindex = 0;

    printf("Argumanty funkcji main:\n----------------\n");
        while(argc--)
            printf("%s\n", *argv++);

    printf("----------------\n");

    socket_address.sll_halen    = ETH_ALEN;

    unsigned char src_mac[6] = {0x00, 0x00, 0x00, 0xaa, 0x00, 0x00};
    unsigned char dest_mac[6] = {0x00, 0x00, 0x00, 0x00, 0x10, 0x20};
    memcpy((void*)buffer, (void*)dest_mac, ETH_ALEN);
    memcpy((void*)(buffer+ETH_ALEN), (void*)src_mac, ETH_ALEN);
    eh->h_proto = htons (0x0800);

    data[0] = 0x45;
        //pole-tos
data[1] = 0x00;
        //calkowita-dlugosc
data[2] = 0x00;
data[3] = 0x54;
        //identyfikacja
data[4] = 0x00;
data[5] = 0x00;
        //flagi
data[6] = 0x40;
        //fragment-offset
data[7] = 0x00;
        //ttl
data[8] = 0x40;
        //protocol
data[9] = 0x01;
        //suma-kontrolna
strcpy(data+10, argv[1]);
strcpy(data+11, argv[2]);
        //adres-zrodlowy
data[12] = 0x0a;
data[13] = 0x00;
data[14] = 0x00;
data[15] = 0x14;
        //adres-docelowy
data[16] = 0x0a;
data[17] = 0x00;
data[18] = 0x00;
data[19] = 0x01;
                //naglowek icmp
        //request 0x08
        //reply 0x00
data[20] = 0x08;
        //kod icmp
data[21] = 0x00;
        //suma-kontrolna
data[22] = 0x00;
data[23] = 0x00;
        //identyfikator-BE i identyfikator-LE
data[24] = 0x00;
data[25] = 0x1f;
        //numer-sekwencji-BE
data[26] = 0x00;
data[27] = 0x01;
        //dane-icmp
data[28] = 0x00;
data[29] = 0x00;
data[30] = 0x00;
data[31] = 0x00;
data[32] = 0x00;
data[33] = 0x00;
data[34] = 0x00;

    #if 1 
        s_out = socket(AF_PACKET, SOCK_RAW, ETH_P_ALL);
        if (s_out == -1) 
        {
        printf ("Nie moge otworzyc gniazda s_out\n");
        }

            strncpy(ifr.ifr_name, INTERFACE, IFNAMSIZ);
            if (ioctl(s_out, SIOCGIFINDEX, &ifr) == -1) 
        {
            perror("SIOCGIFINDEX");
            exit(1);
        }

            ifindex = ifr.ifr_ifindex;
        printf("Pobrano indeks karty NIC: %i\n", ifindex);


socket_address.sll_ifindex  = ifindex;

        send_result = sendto(s_out, buffer, 49, 0,(struct sockaddr*)&socket_address, sizeof(socket_address));
        if (send_result == -1) 
        { 
        printf ("Nie moge wyslac danych! \n"); 
        }
            else 
            {
            printf ("Wyslalem dane do intefejsu: %s \n", INTERFACE);
            }

        #if 1
            printf ("Dane do wyslania: \n");
            for (j=0;j<send_result; j++) 
            {
            printf ("%02x ", *(etherhead+j));
            }
            printf ("\n");
        #endif


#endif
    return EXIT_SUCCESS;
}

如何从命令行输入数据到这个数据[]? strcpy(数据+10, argv[1]); 给出 53 strcpy(数据+11, argv[2]); 给出 54 这是为什么?

这给出了一个编译器warning/error:

data[1] = argv[1];

这里 data[1] 是类型 charargv[1]char* 类型。因为 argv 是一个字符指针列表 (char*).

要复制整个第一个参数,您可以执行类似 strcpy(argv[0], data); 的操作,但这不会检查目标 data 是否有足够的 space,因此长参数会导致错误。

为确保数据足够space,您可以

char* data = (char*) malloc(strlen(argv[2]) +1);

然后你对etherhead做同样的事情:

char* etherhead = (char*) malloc(strlen(argv[1]) +1);

并为他们俩制作一个漂亮的结构:

struct Buffer{
  char* head;
  char* data;
};

Buffer b = { etherhead, data };

//use them
printf("data: %s \n", b.data);

如果您想将它们连接成一个字符串,也可以:

char* headerAndData = (char*) malloc(strlen(argv[1]) + strlen(argv[2]) +1);

sprintf(headerAndData, "%s%s", argv[1], argv[2]);

因为你用 typeconversion 标记了问题,我假设你想要的数据不是字符串。您可以通过多种方式执行此操作,具体取决于您的数据类型。对于整数,您可以说 int i = atoi(argv[1]);。你也可以看看scanf

代码的其他几个问题:

In C, do not cast the returned value from malloc()
always check (!=NULL) the returned value from malloc 
  to assure the operation was successful

main()的argc参数表示参数个数(包括指向程序名的指针为argv[0])

所以,有两个参数

if( 3 != argc )
{ // then invalid parameter count
    printf( "Usage: %s <parm1> <parm2>\n", argv[0] );
    exit( EXIT_FAILURE );
}

// implied else, correct number of parameters

// argv[1] is a pointer to a string that contains the first parameter
// argv[2] is a pointer to a string that contains the second parameter

关于这个问题:

如何从命令行输入数据到这个数据[]? strcpy(数据+10, argv[1]);给出 53 strcpy(data+11, argv[2]);给出 54 这是为什么?

如果贴出的53和54是十进制值,那么它们代表'4'和'5'但是,如果它们是十六进制值,那么它们代表'S'和'T'