c - 是否可以使用 for 循环索引访问结构元素?

标签 c structure packet

我试图通过用户输入形成一个 ip 数据包。我只做了L4。 l7 header 包括我作为字符串使用的数据。对于 L4 header ,用户必须提供 l4 不同字段的值,我尝试将它们转换为 sting 并附加到数据包。我也想对第 3 层进行类似处理。

它工作正常,但在代码中我最终为 L4 的不同领域编写了类似的代码。我在代码块中提到了它们。可以使用 for 循环将所有 4 个 block 转换为单个 block 。

代码部分是:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct l4{
    unsigned short source_port;
    unsigned short dest_port;
    unsigned int length;
    unsigned short checksum;
}l4_struct;

void append_l7(char *packet , FILE *fp) {
    char l7_packet[255];
    fscanf(fp , "%[^\n]%*c" , l7_packet);
    strcpy(packet , l7_packet);
}

void append_l4(char *packet , FILE *fp) {
    char l4_header_string[255] , buf[255];
    memset(buf  , 0 ,  255);
    l4_struct l4_header;

//block 1
    fscanf(fp , "%hd" , &l4_header.source_port);
    sprintf(buf , "%x" , l4_header.source_port);
    strcpy(l4_header_string , buf);
    memset(buf  , 0 ,  255);

//block 2
    fscanf(fp , "%hd" , &l4_header.dest_port);
    sprintf(buf , "%s %.4x" , l4_header_string , l4_header.dest_port);
    strcpy(l4_header_string , buf);
    memset(buf  , 0 ,  255);

//block 3
    fscanf(fp , "%d" , &l4_header.length);
    sprintf(buf , "%s %.4x" , l4_header_string , l4_header.length);
    strcpy(l4_header_string , buf);
    memset(buf  , 0 ,  255);

//block 4
    fscanf(fp , "%hd" , &l4_header.checksum);
    sprintf(buf , "%s %.4x" , l4_header_string , l4_header.checksum);
    strcpy(l4_header_string , buf);
    memset(buf  , 0 ,  255);

//    strcat(l4_header_string , packet);
    sprintf(buf , "%s %s" , l4_header_string , packet);
    strcpy(packet , buf);
}

void append_l3(char *packet , FILE *fp) {

}

int main() {
    FILE *fp = fopen("input_packet.txt" , "r");
    int packet_size = 255; //We can take from user also
    char *packet = (char *)calloc(packet_size , sizeof(char));

    append_l7(packet  , fp);
    append_l4(packet , fp);
//    append_l3(packet , fp);

    //printing packet
    printf("\nPacket:%s\n" , packet);
//    printf("%hd\n%d\n" , sizeof(unsigned short) , sizeof(unsigned int));
    free(fp);
    free(packet);
}

而input_packet.txt是

ab c9 01 00 00 01 00 00 00 00 00 00 09 6d 63 63 6c 65 6c 6c 61 6e 02 63 73 05 6d 69 61 6d 69 03 65 64 75 00 00 01 00 01
58759
53
48
58144

输出:

Packet:e587 0035 0030 e320 ab c9 01 00 00 01 00 00 00 00 00 00 09 6d 63 63 6c 65 6c 6c 61 6e 02 63 73 05 6d 69 61 6d 69 03 65 64 75 00 00 01 00 01

我想要 append_l4() 函数如下所示:

char **dptr = (char **) malloc(sizeof(char *) * 4);
dptr[0] = "source_port";
dptr[1] = "dest_port";
dptr[2] = "length";
dptr[3] = "checksum";

void append_l4(char *packet , FILE *fp) {
    char l4_header_string[255] , buf[255];
    memset(buf  , 0 ,  255);
    l4_struct l4_header;

    for(i = 0; i < 4; i++){
        fscanf(fp , "%(this type varies)" , &l4_header.dptr[i]);
        sprintf(buf , "%s %.4x" , l4_header_string , l4_header.dptr[i]);
        strcpy(l4_header_string , buf);
        memset(buf  , 0 ,  255);
    }

//    strcat(l4_header_string , packet);
    sprintf(buf , "%s %s" , l4_header_string , packet);
    strcpy(packet , buf);
}

这可能吗?如果是,请建议我如何实现这一目标。

Iterating over a struct in C++类似,但它是在 C++ 中。

最佳答案

我的建议 是您尝试使用union,这将允许您在同一内存位置存储“不同”的数据类型。尽管如此,对于所有可能的 field 大小(这似乎是您想要的),您必须平等地处理您的输入数据。我自己已经完成了构建 TCP 数据包的工作,并且以下结构非常有用(特别是对于复制操作)。

union packet_u
{
  uint8_t a[__TOTAL_STRUCT_SIZE__];
  struct
  {
      uint16_t field1;
      uint16_t field2;
      uint32_t field3;
      uint16_t field4;
  }
};

读取输入文件并将其保存在您的结构中应该很简单,所以我会让您继续研究这个想法。此外,您可以更改要迭代的最小大小(即 uint8_t a[...])。

关于c - 是否可以使用 for 循环索引访问结构元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51478725/

相关文章:

c - Linux下使用C语言读取.log文件

c# - Switch-Case 数据包处理的替代方案

packet - 如何做数据包嗅探器?

c - 更多原始(数据包)套接字无法在同一网络接口(interface)上进行通信

c - 我对字符串感到困惑

c++ - 在 C 中,我们可以使用诸如::或 -> 之类的运算符来访问头文件中的预定义方法吗?

python - 为什么以下代码在 codechef 中给出段错误,但在其他地方却工作得绝对正确

C、函数格式化中的结构指针

c - 使用 Excel 值中的指针和结构在 C 中显示问题

mysql - 订单表结构,mysql