使用参数C运行程序

时间:2015-06-03 11:13:26

标签: c type-conversion

我需要帮助如何使用参数运行程序。我需要它运行如下:./ name_of_program parameter1 parameter2 我需要它在data []表中设置参数。

    #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(data + 10,argv [1]); 给53 strcpy(data + 11,argv [2]); 给54 那是为什么?

2 个答案:

答案 0 :(得分:1)

这给出了编译器警告/错误:

data[1] = argv[1];

此处data[1]的类型为charargv[1]的类型为char*。因为argv是一个charpointers列表(char*)。

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

为确保数据有足够的空间,您可以

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

答案 1 :(得分:0)

代码中的其他几个问题:

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(data + 10,argv [1]);得到53 strcpy(数据+ 11,argv [2]);给出了54为什么会这样?

如果发布的53和54是十进制值,那么它们代表&#39; 4&#39;和&#39; 5&#39;但是,如果它们是十六进制值,那么它们代表S&#39; S&#39;和&#39; <&#39;