/********************************************************************* * Process message Functions * *********************************************************************/ void process_arp_request(int sockfd, struct arp_msg *msg) { int i; struct arp_cache_entry cache_entry; bzero(&cache_entry, sizeof(cache_entry)); cache_entry.connfd = sockfd; cache_entry.sll_ifindex = my_index; cache_entry.sll_hatype = msg->hrd; strcpy(cache_entry.ip, msg->sender_ip); for (i = 0; i < IF_HADDR; i++){ cache_entry.mac[i] = msg->sender_mac[i]; } cache_entry.isComplete = 1; cache_entry.isValid = 1; cache_entry.isLocal = 0; // Pertains to the request, insert new entry if (strcmp(my_ip, msg->target_ip) == 0 || isDest(msg->target_ip) ) { puts("----->ARP: DESTINATION."); if ((i = search_cache(msg->sender_ip) == -1)) { puts("----->ARP: I DO pertain to this request. Create new entry for this <senderIP, senderMAC>.\n"); if (insert_entry(cache_entry) < 0) { perror("unable to insert cache entry."); } } else { puts("----->ARP: I DO pertain to this request. Update <senderIP, senderMAC>.\n"); update_cache(i, msg); } // Send ARP reply msg->op = ARP_REP; for (i = 0; i < INET_ADDRSTRLEN; i ++) { msg->target_ip[i] = msg->sender_ip[i]; } printf("Target ip:%s\n", msg->target_ip); for (i = 0; i < IF_HADDR; i++){ msg->target_mac[i] = msg->sender_mac[i]; } strcpy(msg->sender_ip, my_ip); for (i = 0; i < IF_HADDR; i++){ msg->sender_mac[i] = if_hwaddr[my_index][i]; } puts("----->ARP: I'm responsible for sending reply..."); send_arp_msg(sockfd, msg->target_mac, msg); puts("----->ARP: Reply sent.\n"); } else if ((i = search_cache(msg->sender_ip) != -1)) { // There is an existing entry, update puts("----->ARP: I'm not pertain to this request, but I have an existing entry, updating...\n"); update_cache(i, msg); } }
//判断地图是否为死图 int isMapDead(struct sokomap *header,int x,int y,enum direction direct) { switch(direct) { case UP: if(isWall(header,x,y-1) == 1 )//上方为墙 { if(isDest(header,x,y) != 1)//箱子不在目标地址上 { //任意两边为墙地图肯定棍了 if(isWall(header,x-1,y) || isWall(header,x+1,y)) { return 1; } //左上角为墙,同时左边为箱子,也同样的棍 if(isWall(header,x-1,y-1) && isBox(header,x-1,y)) { return 1; } //右上角为墙,右边为箱子,也棍 if(isWall(header,x+1,y-1) && isBox(header,x+1,y)) { return 1; } } //上边一排为墙,此时查看这一排的箱子数量,目标数量,是否相符 int flag = 0;//标志位 int boxNum = 0,destNum = 0; //先向左查询 int count = x; for(;count >=0;count--) { if(isWall(header,count,y-1) != 1)//当不为墙时查询它下边的是否为墙 { if(isWall(header,count,y) != 1)//此时下边也不为墙,则死图的条件不成立,跳出次条件判断 { flag = 1; break; }else { break; } }else//当下边为墙时,跳出循环 { if(isWall(header,count,y) == 1) { break; }else { if(isDest(header,count,y)) { destNum ++; } if(isBox(header,count,y)) { boxNum ++; } } } } if(flag) { break; } //再向右查寻 flag = 0; count = x + 1; for(;count < header -> width;count ++) { if(isWall(header,count,y-1) != 1)//当不为墙时查询它下边的是否为墙 { if(isWall(header,count,y) != 1)//此时下边也不为墙,则死图的条件不成立,跳出次条件判断 { flag = 1; break; }else { break; } }else//当下边为墙时,跳出循环 { if(isWall(header,count,y) == 1) { break; }else { if(isDest(header,count,y)) { destNum ++; } if(isBox(header,count,y)) { boxNum ++; } } } } if(flag) { break; } if(boxNum > destNum)//箱子数量大于目的数量时,证明此地图已经棍了 { return 1; } } break; case DOWN: if(isWall(header,x,y+1) == 1 )//下方为墙 { if(isDest(header,x,y) != 1)//箱子不在目标地址上 { //任意两边为墙地图肯定棍了 if(isWall(header,x-1,y) || isWall(header,x+1,y)) { return 1; } //左下角为墙,同时左边为箱子,也同样的棍 if(isWall(header,x-1,y+1) && isBox(header,x-1,y)) { return 1; } //右下角为墙,右边为箱子,也棍 if(isWall(header,x+1,y+1) && isBox(header,x+1,y)) { return 1; } } //上边一排为墙,此时查看这一排的箱子数量,目标数量,是否相符 int flag = 0;//标志位 int boxNum = 0,destNum = 0; //先向左查询 int count = x; for(;count >=0;count--) { if(isWall(header,count,y+1) != 1)//当不为墙时查询它下边的是否为墙 { if(isWall(header,count,y) != 1)//此时下边也不为墙,则死图的条件不成立,跳出次条件判断 { flag = 1; break; }else { break; } }else//当下边为墙时,跳出循环 { if(isWall(header,count,y) == 1) { break; }else { if(isDest(header,count,y)) { destNum ++; } if(isBox(header,count,y)) { boxNum ++; } } } } if(flag) { break; } //再向右查寻 flag = 0; count = x + 1; for(;count < header -> width;count ++) { if(isWall(header,count,y+1) != 1)//当不为墙时查询它下边的是否为墙 { if(isWall(header,count,y) != 1)//此时下边也不为墙,则死图的条件不成立,跳出次条件判断 { flag = 1; break; }else { break; } }else//当下边为墙时,跳出循环 { if(isWall(header,count,y) == 1) { break; }else { if(isDest(header,count,y)) { destNum ++; } if(isBox(header,count,y)) { boxNum ++; } } } } if(flag) { break; } if(boxNum > destNum)//箱子数量大于目的数量时,证明此地图已经棍了 { return 1; } } break; case LEFT: if(isWall(header,x-1,y) == 1 )//左方为墙 { if(isDest(header,x,y) != 1)//箱子不在目标地址上 { //任意两边为墙地图肯定棍了 if(isWall(header,x,y - 1) || isWall(header,x,y+1)) { return 1; } if(isWall(header,x-1,y -1) && isBox(header,x,y-1)) { return 1; } if(isWall(header,x -1,y+1) && isBox(header,x,y + 1)) { return 1; } } //上边一排为墙,此时查看这一排的箱子数量,目标数量,是否相符 int flag = 0;//标志位 int boxNum = 0,destNum = 0; //先向上查询 int count = y; for(;count >=0;count--) { if(isWall(header,x - 1,count) != 1)//当不为墙时查询它右边的是否为墙 { if(isWall(header,x,count) != 1)//此时右边也不为墙,则死图的条件不成立,跳出次条件判断 { flag = 1; break; }else { break; } }else//当右边为墙时,跳出循环 { if(isWall(header,x,count) == 1) { break; }else { if(isDest(header,x,count)) { destNum ++; } if(isBox(header,x,count)) { boxNum ++; } } } } if(flag) { break; } //再向下查寻 flag = 0; count = y + 1; for(;count < header -> hight;count ++) { if(isWall(header,x - 1,count) != 1)//当不为墙时查询它下边的是否为墙 { if(isWall(header,x,count) != 1)//此时下边也不为墙,则死图的条件不成立,跳出次条件判断 { flag = 1; break; }else { break; } }else//当下边为墙时,跳出循环 { if(isWall(header,x,count) == 1) { break; }else { if(isDest(header,x,count)) { destNum ++; } if(isBox(header,x,count)) { boxNum ++; } } } } if(flag) { break; } if(boxNum > destNum)//箱子数量大于目的数量时,证明此地图已经棍了 { return 1; } } break; case RIGHT: if(isWall(header,x+1,y) == 1 )//右方为墙 { if(isDest(header,x,y) != 1)//箱子不在目标地址上 { //任意两边为墙地图肯定棍了 if(isWall(header,x,y - 1) || isWall(header,x,y+1)) { return 1; } if(isWall(header,x+1,y -1) && isBox(header,x,y-1)) { return 1; } if(isWall(header,x + 1,y+1) && isBox(header,x,y + 1)) { return 1; } } //上边一排为墙,此时查看这一排的箱子数量,目标数量,是否相符 int flag = 0;//标志位 int boxNum = 0,destNum = 0; //先向上查询 int count = y; for(;count >=0;count--) { if(isWall(header,x + 1,count) != 1)//当不为墙时查询它右边的是否为墙 { if(isWall(header,x,count) != 1)//此时右边也不为墙,则死图的条件不成立,跳出次条件判断 { flag = 1; break; }else { break; } }else//当右边为墙时,跳出循环 { if(isWall(header,x,count) == 1) { break; }else { if(isDest(header,x,count)) { destNum ++; } if(isBox(header,x,count)) { boxNum ++; } } } } if(flag) { break; } //再向下查寻 flag = 0; count = y + 1; for(;count < header -> hight;count ++) { if(isWall(header,x + 1,count) != 1)//当不为墙时查询它下边的是否为墙 { if(isWall(header,x,count) != 1)//此时下边也不为墙,则死图的条件不成立,跳出次条件判断 { flag = 1; break; }else { break; } }else//当左边为墙时,跳出循环 { if(isWall(header,x,count) == 1) { break; }else { if(isDest(header,x,count)) { destNum ++; } if(isBox(header,x,count)) { boxNum ++; } } } } if(flag) { break; } if(boxNum > destNum)//箱子数量大于目的数量时,证明此地图已经棍了 { return 1; } } break; } return 0; }