diff --git a/day7/fake_feiq.c b/day7/fake_feiq.c new file mode 100644 index 0000000..1314754 --- /dev/null +++ b/day7/fake_feiq.c @@ -0,0 +1,197 @@ +#include +#include +#include // iconv, 用于转换编码 + +// 将字符串转换为UTF-8编码 +char *convertToUTF8(const char *str) +{ + // 输入字符串的长度 + size_t inlen = strlen(str); + + // 输出缓冲区的长度,假设为输入长度的3倍(UTF-8编码最多占用3个字节) + size_t outlen = inlen * 3; + + // 创建转换句柄 + iconv_t cd = iconv_open("UTF-8", "GB2312"); // 从 GB2312 转换为 UTF-8 + + // 分配输出缓冲区 + char *outbuf = (char *)malloc(outlen); + if (outbuf == NULL) + { + perror("Memory allocation failed"); + return NULL; + } + + // 进行转换 + char *inbuf = (char *)str; + char *outptr = outbuf; + + if (iconv(cd, &inbuf, &inlen, &outptr, &outlen) == (size_t)-1) + { + perror("Conversion failed"); + free(outbuf); + iconv_close(cd); + return NULL; + } + + // 关闭转换句柄 + iconv_close(cd); + + // 添加字符串结束符 + *outptr = '\0'; + + return outbuf; +} + +// 将字符串转换为GB2312编码 +char *convertToGB2312(const char *str) +{ + // 输入字符串的长度 + size_t inlen = strlen(str); + + // 输出缓冲区的长度,假设为输入长度的3倍(UTF-8编码最多占用3个字节) + size_t outlen = inlen * 3; + + // 创建转换句柄 + iconv_t cd = iconv_open("GB2312", "UTF-8"); // 从 UTF-8 转换为 GB2312 + + // 分配输出缓冲区 + char *outbuf = (char *)malloc(outlen); + if (outbuf == NULL) + { + perror("Memory allocation failed"); + return NULL; + } + + // 进行转换 + char *inbuf = (char *)str; + char *outptr = outbuf; + + if (iconv(cd, &inbuf, &inlen, &outptr, &outlen) == (size_t)-1) + { + perror("Conversion failed"); + free(outbuf); + iconv_close(cd); + return NULL; + } + + // 关闭转换句柄 + iconv_close(cd); + + // 添加字符串结束符 + *outptr = '\0'; + + return outbuf; +} + +int main(int argc, char const *argv[]) +{ + if (argc < 2) + { + printf("usage: %s \n", argv[0]); + return -1; + } + + while (1) + { + + // 1. 初始化libnet + char err_buf[LIBNET_ERRBUF_SIZE] = ""; + libnet_t *net = libnet_init(LIBNET_RAW4, argv[1], err_buf); + if (net == NULL) + { + printf("libnet_init error: %s\n", err_buf); + return -2; + } + printf("libnet_init success\n"); + + // 2. 构建数据 + // 2.1 UDP + u_char msg_data[64] = ""; + u_char say_what[64] = ""; + printf("请输入要发送的内容:"); + // scanf("%s", say_what); + fgets(say_what, sizeof(say_what), stdin); // 比 scanf 的优点是可以输入空格 + say_what[strlen(say_what) - 1] = '\0'; // 去掉最后的换行符 + + sprintf(msg_data, "1:%d:%s:%s:%d:%s", 123, convertToGB2312("发送者"), convertToGB2312("匿名PC"), 32, convertToGB2312(say_what)); + int msg_data_len = strlen(msg_data) + strlen(msg_data) % 2; // 整数补齐偶数位,strlen(msg_data)%2 : 偶数+0,奇数+1 + printf("msg_data_len = %d ---> %s\n", msg_data_len, convertToUTF8(msg_data)); + + // 2.1.2 构建UDP数据包 + libnet_ptag_t udp_tag = 0; + udp_tag = libnet_build_udp( + 2425, // 源端口 + 2425, // 目的端口 + 8 + msg_data_len, // UDP数据包长度 + 0, // 校验和,0为自动计算 + msg_data, // 数据 + msg_data_len, // 数据长度 + net, // libnet句柄 + 0 // 0 表示构造新的报文,>0表示在已有报文基础上追加 + ); + if (udp_tag != -1) + { + printf("udp tag: %d\n", udp_tag); + } + + // 2.2 ip 报 + libnet_ptag_t ip_tag = libnet_build_ipv4( + 20 + 8 + msg_data_len, // IP数据包总长度 + 0, // tos + 0, // id, 0表示自动计算 + 0, // 标志位 + 32, // TTL + 17, // 上层协议号,17表示UDP + 0, // 校验和,0表示自动计算 + inet_addr("10.12.156.196"), // 源IP地址,网络序 + inet_addr("10.12.156.178"), // 目的IP地址,网络序 + NULL, // 负载数据,这里不需要 + 0, // 负载数据长度 + net, // libnet句柄 + 0 // 协议标记,0表示构造新的报文, >0表示在已有报文基础上追加 + ); // 构造IP数据包,返回值是新生成的协议块标记 + if (ip_tag != -1) + { + printf("ip tag: %d\n", ip_tag); + } + + // 2.3 构建以太网数据包 + char sender_mac[128] = "4c:e1:73:47:16:3a"; // 发送者原始 MAC + char recv_mac[128] = "00:d8:61:03:45:65"; // 接收者原始 MAC + unsigned char dst_mac[8] = {}; // 目的 MAC + unsigned char src_mac[8] = {}; // 发送者 MAC + sscanf(sender_mac, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &src_mac[0], &src_mac[1], &src_mac[2], &src_mac[3], &src_mac[4], &src_mac[5]); + sscanf(recv_mac, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &dst_mac[0], &dst_mac[1], &dst_mac[2], &dst_mac[3], &dst_mac[4], &dst_mac[5]); + printf("src_mac: %s dst_mac: %s\n", src_mac, dst_mac); + libnet_ptag_t eth_tag = libnet_build_ethernet( + dst_mac, // 目的MAC地址 + src_mac, // 源MAC地址 + 0x0800, // 上层协议类型,0x0800表示IP + NULL, // 负载数据,这里不需要 + 0, // 负载数据长度 + net, // libnet句柄 + 0 // 协议标记,0表示构造新的报文, >0表示在已有报文基础上追加 + ); + if (eth_tag != -1) + { + printf("eth tag: %d\n", eth_tag); + } + + // 3. 发送数据 + int send_len = libnet_write(net); + if (send_len == -1) + { + printf("libnet_write error: %s\n", libnet_geterror(net)); + } + else + { + printf("libnet_write success, send bytes: %d\n", send_len); + } + + // 释放资源 + libnet_destroy(net); + } + + return 0; +} diff --git a/day7/libnet_demo1.c b/day7/libnet_demo1.c new file mode 100644 index 0000000..ac66c51 --- /dev/null +++ b/day7/libnet_demo1.c @@ -0,0 +1,99 @@ +#include +#include + +int main(int argc, char const *argv[]) +{ + if (argc < 2) + { + printf("usage: %s \n", argv[0]); + return -1; + } + + // 1. 初始化libnet + char err_buf[LIBNET_ERRBUF_SIZE] = ""; + libnet_t *net = libnet_init(LIBNET_RAW4, argv[1], err_buf); + if (net == NULL) + { + printf("libnet_init error: %s\n", err_buf); + return -2; + } + printf("libnet_init success\n"); + + // 2. 构建数据 + // 2.1 UDP + u_char data_buf[64] = ""; + fgets(data_buf, sizeof(data_buf), stdin); + data_buf[strlen(data_buf) - 1] = '\0'; + int data_len = strlen(data_buf) + strlen(data_buf) % 2; // UDP数据包长度必须为偶数 + + // 2.1.2 构建UDP数据包 + libnet_ptag_t udp_tag = 0; + udp_tag = libnet_build_udp( + 8001, // 源端口 + 8000, // 目的端口 + 8 + data_len, // UDP数据包长度 + 0, // 校验和,0为自动计算 + data_buf, // 数据 + data_len, // 数据长度 + net, // libnet句柄 + 0 // 0 表示构造新的报文,>0表示在已有报文基础上追加 + ); + if (udp_tag != -1) + { + printf("udp tag: %d\n", udp_tag); + } + + // 2.2 ip 报 + libnet_ptag_t ip_tag = libnet_build_ipv4( + 20 + 8 + data_len, // IP数据包总长度 + 0, // tos + 0, // id, 0表示自动计算 + 0, // 标志位 + 32, // TTL + 17, // 上层协议号,17表示UDP + 0, // 校验和,0表示自动计算 + inet_addr("10.12.156.232"), // 源IP地址,网络序 + inet_addr("10.12.156.178"), // 目的IP地址,网络序 + NULL, // 负载数据,这里不需要 + 0, // 负载数据长度 + net, // libnet句柄 + 0 // 协议标记,0表示构造新的报文, >0表示在已有报文基础上追加 + ); // 构造IP数据包,返回值是新生成的协议块标记 + if (ip_tag != -1) + { + printf("ip tag: %d\n", ip_tag); + } + + // 2.3 构建以太网数据包 + u_char dst_mac[6] = {0x00, 0xd8, 0x61, 0x03, 0x45, 0x65}; // 目的MAC地址 + u_char src_mac[6] = {0x00, 0x0c, 0x29, 0x4e, 0x4a, 0x4c}; // 源MAC地址 + libnet_ptag_t eth_tag = libnet_build_ethernet( + dst_mac, // 目的MAC地址 + src_mac, // 源MAC地址 + 0x0800, // 上层协议类型,0x0800表示IP + NULL, // 负载数据,这里不需要 + 0, // 负载数据长度 + net, // libnet句柄 + 0 // 协议标记,0表示构造新的报文, >0表示在已有报文基础上追加 + ); + if (eth_tag != -1) + { + printf("eth tag: %d\n", eth_tag); + } + + // 3. 发送数据 + int send_len = libnet_write(net); + if (send_len == -1) + { + printf("libnet_write error: %s\n", libnet_geterror(net)); + } + else + { + printf("libnet_write success, send bytes: %d\n", send_len); + } + + // 释放资源 + libnet_destroy(net); + + return 0; +}