/* invoked within arp_act() when an ARP reply message comes, or within * arp_respond() when an ARP inquiry message comes. They both running in a * bottom half, so arp_learn() is never re-entered. * */ static struct arp_record * arp_learn(u8 *comer_mac, u32 comer_ip){ int index = iphash(comer_ip )% ARP_TBL_LEN; struct arp_record *record = arptbl[index]; while(record){ if( record->his_ip == comer_ip) break; record = record->next; } /* ok, this ARP message comes from a known host, try update */ if(record){ memcpy( record->his_mac, comer_mac, 6); } else{ /* a new IP, we will learn it */ record = kmalloc2( sizeof( struct arp_record), 0 ); record->his_ip = comer_ip; memcpy( record->his_mac, comer_mac, 6); LL_I( arptbl[index], record); //oprintf("ARP Learn:" ); //print_mac(comer_mac); //oprintf("<=="); //print_ip(comer_ip); //oprintf("\n"); } return record; }
/* @DESC * Now, an IP datagram wanna go out. We let arp layer determine it's next hop, * to a gateway, or directly to another host in LAN. */ void arp_down(struct sk_buff *skb){ struct iphdr * iphdr = skb->iphdr; unsigned yourip = ntohl(iphdr->yourip); //unsigned myip = ntohl(iphdr->myip); struct net_device * dev = skb->dev; assert(dev); memcpy(skb->ethhdr->mymac, skb->dev->mac, 6); skb->ethhdr->protocol = htons(0x0800); //skb_cursor_up(skb, sizeof(struct ethhdr)); unsigned nexthop; if((yourip & dev->ipmask) == (dev->ip & dev->ipmask)){ nexthop = yourip; } else nexthop = dev->gateway_ip; u8 *dest_mac = arp_lookup(nexthop); if(dest_mac){ memcpy(skb->ethhdr->yourmac, dest_mac, 6); waiting_for_transmit(skb); } else{ oprintf("[!]\n"); cli(); int index = iphash(yourip )% ARP_TBL_LEN; //oprintf("hash ip:%s, got index:%u", mk_ipstr(yourip), index); LL_I( later_down[index], skb); sti(); arp_inquire(yourip); } }
static u8 *arp_lookup(u32 ip){ int index = iphash(ip) % ARP_TBL_LEN; struct arp_record * root = arptbl[index]; struct arp_record *it = 0; LL_SCAN_ON_KEY(root, his_ip, ip, it); if(it){ return (u8*)it->his_mac; } return 0; }
/* when we receive an ARP reply on operation 1 */ static void arp_act(struct sk_buff *skb){ struct arphdr *arphdr = skb->arphdr; assert(arphdr->operation == 2 && arphdr->yourmac[3] == skb->dev->mac[3]); struct arp_record * record = arp_learn( arphdr->mymac ,arphdr->myip); int index = iphash(record->his_ip )% ARP_TBL_LEN; struct sk_buff * waiting = later_down[index]; //oprintf("laterdown try waked!target ip:%s, got index:%u\n", mk_ipstr(record->his_ip), index); while(waiting){ oprintf("$"); struct sk_buff *_next = waiting->next; if(waiting->iphdr->yourip == htonl(record->his_ip)){ //oprintf("find one in later_down\n"); memcpy(waiting->ethhdr->yourmac, record->his_mac, 6); cli(); LL_DEL(later_down[index], waiting); sti(); //BUG waiting_for_transmit(waiting); } waiting = _next; } }
char * wwwlogin(struct userec *user, int ipmask) { FILE *fp, *fp1; int n, dolog = 0, st, clubnum, uid, i, nsearch; struct user_info *u; char ULIST[STRLEN]; char genbuf[256], *urlbase, fname[80]; uid = getusernum(user->userid) + 1; if ((urlbase = check_multi(user->userid, uid))) return urlbase; if (strcasecmp(user->userid, "guest") && count_uindex(uid) >= 3) http_fatal("您已经登录了三个帐号,不能再登录了"); // 如果要限制WWW登录窗口数 就打开这个注释. lepton gethostname(genbuf, 256); sprintf(ULIST, MY_BBS_HOME "/%s.%s", ULIST_BASE, genbuf); fp = fopen(ULIST, "a"); flock(fileno(fp), LOCK_EX); nsearch = NSEARCH; //if (strcasecmp(user->userid, "guest")) // nsearch = MAXACTIVE / 4; for (i = 0, n = iphash(fromhost) * (MAXACTIVE / NHASH); i < nsearch; i++, n++) { if (n >= MAXACTIVE) n = 0; u = &(shm_utmp->uinfo[n]); if (u->active && u->pid == 1 && ((now_t - u->lasttime) > 20 * 60 || u->wwwinfo.iskicked)) { st = u->lasttime - u->wwwinfo.login_start_time; if (st > 86400) { errlog("Strange long stay time,%d!, drop %s", st, u->userid); st = 86400; } sprintf(genbuf, "%s drop %d www", u->userid, st); newtrace(genbuf); remove_uindex(u->uid, n + 1); bzero(u, sizeof (struct user_info)); } if (!dolog && u->active == 0) { u_info = u; bzero(u, sizeof (struct user_info)); u->active = 1; u->uid = uid; u->pid = 1; //u->pid = thispid; //modify by mintbaggio@BMY for kill www user u->mode = LOGIN; if (strcasecmp(user->userid, "guest")) u_info->unreadmsg = get_unreadmsg(user->userid); else u_info->unreadmsg = 0; u->userlevel = user->userlevel; u->lasttime = now_t; u->curboard = 0; if (user_perm(user, PERM_LOGINCLOAK) && (user->flags[0] & CLOAK_FLAG)) u->invisible = YEA; u->pager = 0; if (user->userdefine & DEF_FRIENDCALL) u->pager |= FRIEND_PAGER; if (user->flags[0] & PAGER_FLAG) { u->pager |= ALL_PAGER; u->pager |= FRIEND_PAGER; } if (user->userdefine & DEF_FRIENDMSG) u->pager |= FRIENDMSG_PAGER; if (user->userdefine & DEF_ALLMSG) { u->pager |= ALLMSG_PAGER; u->pager |= FRIENDMSG_PAGER; } strsncpy(u->from, fromhost, 24); strsncpy(u->username, user->username, NAMELEN); strsncpy(u->userid, user->userid, IDLEN + 1); getrandomstr(u->sessionid); if (strcasecmp(user->userid, "guest")) initfriends(u); else memset(u->friend, 0, sizeof (u->friend)); urlbase = makeurlbase(n); w_info = &(u_info->wwwinfo); w_info->login_start_time = now_t; w_info->ipmask = ipmask; if (strcasecmp(user->userid, "guest")) { sethomefile(fname, user->userid, "clubrights"); if ((fp1 = fopen(fname, "r")) == NULL) { memset(u_info->clubrights, 0, 4 * sizeof (int)); } else { while (fgets(genbuf, STRLEN, fp1) != NULL) { clubnum = atoi(genbuf); u_info->clubrights[clubnum / 32] |= (1 << clubnum % 32); } fclose(fp1); } set_my_cookie(); } else { memset(u_info->clubrights, 0, 4 * sizeof (int)); w_info->t_lines = 20; w_info->att_mode = 0; w_info->doc_mode = 1; } dolog = 1; add_uindex(u->uid, n + 1); } }