# include"include/list.h"
# include
# include
# define list_entry(ptr,type,member) \
(type *)( (char *)ptr - offsetof(type,member))
# define list_for_each_entry(pos,head,member) \
for( pos = list_entry((head)->next,typeof(*pos),member); \
&pos->member !=(head);
pos = list_entry(pos->member.next,typeof(*pos),member))
# define list_for_each_entry_safe(pos,q,head,member) \
for( pos = list_entry(head->next,typeof(*pos),member),
q = list_entry(pos->member.next,typeof(*pos),member);
&pos->member != head;
pos = q,
q = list_entry(pos->member.next,typeof(*q),member)
struct list_head{
struct list_head *next,*prev;
};
struct listnode{
struct list_head list;
int number;
};
static inline void init_list_head(struct list_head *list){
list->next = list->prev = list;
}
static inline void list_insert(struct list_head *new,
struct list_head *prev,
struct list_head *next)
{
next - > prev = new;
prev -> next = new;
new -> next = next;
new -> prev = prev;
}
static inline void list_add_tail(struct list_head *new,struct list_head *head)
{
list_insert(new,head->prev,head);
}
static inline void list_delete_enrty(struct list_head *entry)
{
entry->next->prev = entry->prev;
entry->prev->next = entry->next;
}
void list_example()
{
struct list_head list;
init_list_head(&list);
// 初始化链表,定义一个list_head指针,并且使得list_head的前驱和后继都指向自己
// for 循环构造10个链表项,每一个链表项中的数据从0~9取值。
// 每一个都是:创建链表,分配空间,然后赋数据值,并添加到表尾。
for(int i = 0; i < 10; i++){
struct listnode *node = malloc(sizeof(struct listnode));
node ->number = i;
list_add_tail(&node->list,&list);
}
// 初始化链表完成
fprintf(stdout,"list all numbers : \n");
struct listnode *entry;
// list_for_each_entry的成员分别为
// list_for_each_entry(结构体成员,头指针,指针成员(或者结构体成员的部分))
list_for_each_entry(entry,&list,list){
fprintf(stdout,"%d\n",enrty->number);
}
fprintf(stdout,"list only odd numbers and remove others: \n");
struct listnode *q;
list_for_each_entry_safe(entry,q,&list,list){
if(entry->number % 2 == 0){
list_delete_entry(&entry->list);
free(entry);
}
else{
fprintf(stdout,"%d\n",entry->number);
}
}
}
广播网络——广播网络实现
如何构建一个多节点网络?
- 两个节点互连 Host 1(10.0.0.1/8) ——全双工链路——Host 2(10.0.0.2/8)
- 多个节点互连 Host 1(10.0.0.1/8)—— Hub ——Host 2(10.0.0.2/8)——Host 3(10.0.0.3/8)
- 广播网络
-
已知网络端口数据结构和发送数据包函数
// 网络端口数据结构 typedef struct{ struct list_head list; int fd; int index; u8 mac[ETH_ALEN]; // 定义以太网接口mac地址长度 char name[16]; }iface_info_t; // 发送数据包函数 void iface_send_packet(iface_info_t *iface, const char *packet, int len){ struct sockaddr_11 addr; // fill addr...,omitted sendto(iface->fd,packet,len,0,&addr,sizeof(addr)); } // 节点广播的逻辑 foreach iface in iface_list: if iface != rx_iface; iface_send_packet(iface, packet,len);
-
decive_internal.c
-
介绍memset库函数
void *memset(void *str, int c, size_t n) str - 指向要填充的内存块 c - 要被设置的值,该值以 int 形式传递,但是函数在填充内存块时是使用该值的无符号字符形式。
n - 要被设置为该值的字符数
- 举一个memset的例子
# include
# include int main() { char str[50]; strcpy(str,"This is string.h library function"); puts(str); memstr(str,'$',7); puts(str); return 0; } // 效果: This is string.h library function // 效果: $$$$$$$ string.h library function
-
# include"headers.h"
# include "base.h"
# include "ether.h"
# include "log.h"
# include
# include
ustack_t *instance;
// 注意两个结构体
typedef struct{
struct list_head iface_list;
int nifs;
struct pollfd *fds;
}ustack_t;
typedef struct{
struct list_head list;
int fd;
int index;
u8 mac[ETH_ALEN];
char name[16];
} iface_info_t;
// 查找对应于fd文件描述符的节点,返回指向该节点的指针
iface_info_t *fd_to_iface(int fd)
{
iface_info_t *iface = NULL;
/*依然是三个变量的遍历,list_for_each_entry,首先是指向结构体的指针
然后是头指针,最后是member变量
所以首先指向结构体的指针iface_info_t *iface,然后是头指针,存储在ustack_t
里面的 iface_list,也是这个成员类型,然后访问成员,
在iface_info_t 里面是 list*/
list_for_each_entry(iface, &instance->iface_list,list){
if(iface -> fd == fd)
return fd;
}
// 找不到的错误判断
log(ERROR, "Could not find the desired interface according to fd %d",fd);
return NULL;
}
// 发送数据包函数
void iface_send_packet(iface_info_t *iface, const char *packet, int len)
{
struct sockaddr_11 addr;
memset(&addr,0,sizeof(struct sockaddr_11));
// 类似于清零 *** 作,把addr中的sizeof(struct sockaddr_11)大小的字节变为0
// addr填充
addr.sll_family = AF_PACKET;
addr.sll_ifindex = iface -> index;
addr.sll_halen = ETH_ALEN;
addr.sll_protocol = htons(ETH_P_ARP);
struct ether_header *eh = (struct ether_header *)packet;
memcpy(addr.slll_addr,eh->ether_dhost,ETH_ALEN);
if(sendto(iface->id,packet,len,0,(const struct sockaddr *)&addr,
sizeof(struct sockaddr_11)) < 0){
perror("Send raw packet failed");
}
}
int open_device(const char *dname)
{
int sd = socket(AF_PACKET,SOCK_RAW,htons(ETH_P_ALL));
if(sd < 0){
perror("creating SOCK_RAW failed!");
return -1;
}
struct ifreq ifr;
bzero(&ifr,sizeof(struct ifreq));
// 置零 *** 作
strcpy(ifr.ifr_name,dname);
if(ioctl(sd,SIOCGIFINDEX,&ifr)< 0){
perror("ioctl() SIOCGIFINDEX failed!");
return -1;
}
struct sockaddr_11 sll;
bzero(&sll,sizeof(sll));
sll.sll_family = AF_PACKET;
sll.sll_ifindex = ifr.ifr_index;
if(bind((int)sd, (struct sockaddr *)&sll,sizeof(sll)) < 0){
perror("binding to device failed!");
return -1;
}
if(ioctl(sd,SIOCGIFHWADDR,&ifr) < 0){
perror("Start(): SIOCGIFHWADDR failed!");
return -1;
}
// We could still capture all the packets even if not in promisc mode.
# if 0
struct packet_mreq mr;
bzero(&mr,sizeof(mr));
mr.mr_ifindex = sll.sll_ifindex;
mr.mr_type = PACKET_MR_PROMISC;
if(setsockopt(sd,SOL_PACKET, PACKET_ADD_MEMBERSHIP,&mr,sizeof(mr)) < 0){
perror("Start():setsockopt() PACKET_ADD_MEMBERSHIP failed!");
return -1;
}
# endif
return sd;
}
int read_iface_info(iface_info_t *iface)
{
int fd = open_device(iface->name);
iface->fd = fd;
int s = socket(AF_INET,SOCK_DGRAM,0);
struct ifreq ifr;
strcpy(ifr.ifr_name, iface->name);
ioctl(s,SIOCGIFINDEX,&ifr);
memcpy(&iface->mac,ifr.ifr_hwaddr.sa_data,sizeof(iface->mac));
// As a broadcast(hub),its interfaces have no IP address.
# if 0
struct in_addr ip,mask;
// get ip address
if(ioctl(fd,SIOCGIFADDR,*ifr) < 0){
perror("Get IP address failed");
exit(1);
}
ip = ((struct sockaddr_in*)&ifr.ifr_addr)->sin_addr;
iface->ip = ntol(*(u32 *)&ip);
strcpy(iface->ip_str,inet_ntoa(ip));
// get net mask
if(ioctl(fd,SIOCGIFNETMASK,&ifr) < 0){
perror("Get IP mask failed");
exit(1);
}
mask = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr;
iface->mask = ntol(*(u32*)&mask);
#endif
return fd;
}
static void find_available_ifaces()
{
init_list_head(&instance->iface_list);
struct ifaddrs *addrs,*addr;
getifaddrs(&addrs);
for(addr = addrs;addr !=NULL;addr = addr->ifa_next){
if(addr->ifa_addr && addr->ifa_addr->sa_family==AF_PACKET && \
strstr(addr->ifa_name,"-eth")!=NULL){
iface_info_t *iface = malloc(sizeof(iface_info_t));
bzero(iface,sizeof(iface_info_t));
init_list_head(&iface->list);
strcpy(iface->name,addr->ifa_name);
list_add_tail(&iface->list,&instance->iface_list);
instance->nifs +=1;
}
}
freeifaddrs(addrs);
if(instace->nifs == 0){
log(ERROR,"could not find available interfaces.");
exit(1);
}
char dev_names[1024]="";
iface_info_t *iface = NULL;
list_for_each_entry(iface,&instance->iface_list,list){
sprintf(dev_names + strlen(dev_names),"%s",iface->name);
}
log(DEBUG,"find the following interfaces:%s.",dev_names);
}
void init_all_ifaces()
{
find_available_ifaces();
instance-> fds = malloc(sizeof(struct pollfd)*instance->nifs);
bzero(instance->fds,sizeof(struct pollfd)*instance->nifs);
iface_info_t *iface = NULL;
int i = 0;
list_for_each_entry(iface,&instance->iface_list,list){
int fd = read_iface_info(iface);
instance->fds[i].fd=fd;
instance ->fds[i].events = POLLIN;
i+=1;
}
}
void init_ustack()
{
instance = malloc(sizeof(ustack_t));
bzero(instance,sizeof(ustack_t));
init_list_head(&instance->iface_list);
init_all_ifaces();
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)