/* 打印以太网帧的包头信息 */ void print_frame( struct ether_header * peth ) { /* 定义一个数组,用于存储把mac地址转换成字符串后的字符串 */ char buf[ 18 ]; printf("\n================================== 第 %d 个包 =======================================\n\n", global.packet_num ); printf("==== 以太网帧信息 =====\n"); char * shost = peth->ether_shost; mac_to_str( shost, buf ); printf("源以太网地址: %s\n", buf ); char * dhost = peth->ether_dhost; mac_to_str( dhost, buf ); printf("目的以太网地址:%s\n", buf ); }
static str_t httpapp_user_binding( user_t * u, u08 comma ) { str_t macs = { 0, 0 }; mac_mapping_t * m = 0; if (!u) return MAKE_STRING("{}"); while (0 != (m = get_next_mac(m))) { if (m->user == u) { char mac[18]; str_t mac_str = __make_string( mac, 18 ); mac_to_str( mac, &m->eth_addr ); mac[17] = ','; append_string( &macs, &mac_str ); } } macs.str[macs.len - 1] = 0; return fmt( 256, "{uname: \"%s\",macs: \"%s\"}%c", u->name, macs.str, comma ? ',' : ' '); }
void arptab_insert( u08 iface, u32 net_addr, mac_addr phys_addr ) { arptab_entry * e = arptab_findslot( net_addr ); if (e->net_addr != net_addr) { char phys[32]; log_printf( "arp: new mapping %u.%u.%u.%u -> %s iface=%d\n", net_addr & 0xff, net_addr >> 8 & 0xff, net_addr >> 16 & 0xff, net_addr >> 24 & 0xff, mac_to_str( phys, &phys_addr ), iface ); }
void print_arp( struct arphdr * parp ) { printf("硬件类型: %d ", ntohs(parp->ar_hrd) ); switch( ntohs( parp->ar_hrd ) ){ case ARPHRD_ETHER: printf("Ethernet 10/100Mbps.\n"); break; case ARPHRD_EETHER: printf("Experimental Ethernet.\n"); break; case ARPHRD_AX25: printf("AX.25 Level 2.\n"); break; case ARPHRD_PRONET: printf("PROnet token ring.\n"); break; case ARPHRD_IEEE802: printf("IEEE 802.2 Ethernet/TR/TB.\n"); break; case ARPHRD_APPLETLK: printf("APPLEtalk.\n"); break; case ARPHRD_ATM: printf("ATM.\n"); break; case ARPHRD_IEEE1394: printf("IEEE 1394 IPv4 .\n"); break; default: printf("Unknow.\n"); break; } printf("映射的协议地址类型: %d ", ntohs(parp->ar_pro) ); switch( ntohs(parp->ar_pro) ){ case ETHERTYPE_IP: printf("IP.\n"); break; default: printf("error.\n"); break; } printf("硬件地址长度: %d\n", parp->ar_hln ); printf("协议地址长度: %d\n", parp->ar_pln ); printf("操作码: %d ", ntohs(parp->ar_op) ); switch( ntohs(parp->ar_op) ){ case ARPOP_REQUEST: printf("ARP 请求.\n"); break; case ARPOP_REPLY: printf("ARP 应答.\n"); break; case ARPOP_RREQUEST: printf("RARP 请求.\n"); break; case ARPOP_RREPLY: printf("RARP 应答.\n"); break; case ARPOP_InREQUEST: printf("InARP 请求.\n"); break; case ARPOP_InREPLY: printf("InARP 应答.\n"); break; case ARPOP_NAK: printf("(ATM)ARP NAK.\n"); break; default: printf("arp 操作码错误.\n"); break; } char * addr = (char*)(parp + 1); char buf[18]; mac_to_str( addr, buf ); printf("发送端以太网地址: %s\n", buf ); printf("发送端IP地址: %s\n", inet_ntoa( *(struct in_addr *)(addr+6) )); mac_to_str( addr+10, buf ); printf("目的以太网地址: %s\n", buf ); printf("目的IP地址: %s\n", inet_ntoa( *(struct in_addr *)(addr+16) )); }
int nmrp_do(struct nmrpd_args *args) { struct nmrp_pkt tx, rx; uint8_t *src, dest[6]; uint16_t len, region; char *filename; time_t beg; int i, status, ulreqs, expect, upload_ok, autoip; struct ethsock *sock; uint32_t intf_addr; void (*sigh_orig)(int); struct { struct in_addr addr; struct in_addr mask; } PACKED ipconf; if (args->op != NMRP_UPLOAD_FW) { fprintf(stderr, "Operation not implemented.\n"); return 1; } if (!mac_parse(args->mac, dest)) { fprintf(stderr, "Invalid MAC address '%s'.\n", args->mac); return 1; } if ((ipconf.mask.s_addr = inet_addr(args->ipmask)) == INADDR_NONE) { fprintf(stderr, "Invalid subnet mask '%s'.\n", args->ipmask); return 1; } if (!args->ipaddr) { autoip = true; /* The MAC of the device that was used to test this utility starts * with a4:2b:8c, hence 164 (0xa4) and 183 (0x2b + 0x8c) */ args->ipaddr = "10.164.183.252"; if (!args->ipaddr_intf) { args->ipaddr_intf = "10.164.183.253"; } } else if (args->ipaddr_intf) { autoip = true; } else { autoip = false; } if ((ipconf.addr.s_addr = inet_addr(args->ipaddr)) == INADDR_NONE) { fprintf(stderr, "Invalid IP address '%s'.\n", args->ipaddr); return 1; } if (args->ipaddr_intf && (intf_addr = inet_addr(args->ipaddr_intf)) == INADDR_NONE) { fprintf(stderr, "Invalid IP address '%s'.\n", args->ipaddr_intf); return 1; } if (args->file_local && strcmp(args->file_local, "-") && access(args->file_local, R_OK) == -1) { fprintf(stderr, "Error accessing file '%s'.\n", args->file_local); return 1; } if (args->file_remote) { if (!tftp_is_valid_filename(args->file_remote)) { fprintf(stderr, "Invalid remote filename '%s'.\n", args->file_remote); return 1; } } if (args->region) { region = htons(to_region_code(args->region)); if (!region) { fprintf(stderr, "Invalid region code '%s'.\n", args->region); return 1; } } else { region = 0; } status = 1; sock = ethsock_create(args->intf, ETH_P_NMRP); if (!sock) { return 1; } gsock = sock; garp = 0; sigh_orig = signal(SIGINT, sigh); if (!autoip) { status = is_valid_ip(sock, &ipconf.addr, &ipconf.mask); if (status <= 0) { if (!status) { fprintf(stderr, "Address %s/%s cannot be used on interface %s.\n", args->ipaddr, args->ipmask, args->intf); } goto out; } } else { if (verbosity) { printf("Adding %s to interface %s.\n", args->ipaddr_intf, args->intf); } if (ethsock_ip_add(sock, intf_addr, ipconf.mask.s_addr, &gundo) != 0) { goto out; } } if (ethsock_set_timeout(sock, args->rx_timeout)) { goto out; } src = ethsock_get_hwaddr(sock); if (!src) { goto out; } memcpy(tx.eh.ether_shost, src, 6); memcpy(tx.eh.ether_dhost, dest, 6); tx.eh.ether_type = htons(ETH_P_NMRP); msg_init(&tx.msg, NMRP_C_ADVERTISE); msg_opt_add(&tx.msg, NMRP_O_MAGIC_NO, "NTGR", 4); msg_hton(&tx.msg); i = 0; upload_ok = 0; beg = time(NULL); while (1) { printf("\rAdvertising NMRP server on %s ... %c", args->intf, spinner[i]); fflush(stdout); i = (i + 1) & 3; if (pkt_send(sock, &tx) < 0) { perror("sendto"); goto out; } status = pkt_recv(sock, &rx); if (status == 0 && memcmp(rx.eh.ether_dhost, src, 6) == 0) { break; } else if (status == 1) { goto out; } else { if ((time(NULL) - beg) >= 60) { printf("\nNo response after 60 seconds. Bailing out.\n"); goto out; } } } printf("\n"); expect = NMRP_C_CONF_REQ; ulreqs = 0; do { if (expect != NMRP_C_NONE && rx.msg.code != expect) { fprintf(stderr, "Received %s while waiting for %s!\n", msg_code_str(rx.msg.code), msg_code_str(expect)); } msg_init(&tx.msg, NMRP_C_NONE); status = 1; switch (rx.msg.code) { case NMRP_C_ADVERTISE: printf("Received NMRP advertisement from %s.\n", mac_to_str(rx.eh.ether_shost)); status = 1; goto out; case NMRP_C_CONF_REQ: tx.msg.code = NMRP_C_CONF_ACK; msg_opt_add(&tx.msg, NMRP_O_DEV_IP, &ipconf, 8); msg_opt_add(&tx.msg, NMRP_O_FW_UP, NULL, 0); #ifdef NMRPFLASH_SET_REGION if (region) { msg_opt_add(&tx.msg, NMRP_O_DEV_REGION, ®ion, 2); } #endif expect = NMRP_C_TFTP_UL_REQ; printf("Received configuration request from %s.\n", mac_to_str(rx.eh.ether_shost)); memcpy(tx.eh.ether_dhost, rx.eh.ether_shost, 6); printf("Sending configuration: ip %s, mask %s.\n", args->ipaddr, args->ipmask); memcpy(arpmac, rx.eh.ether_shost, 6); memcpy(&arpip, &ipconf.addr, sizeof(ipconf.addr)); if (ethsock_arp_add(sock, arpmac, &arpip) != 0) { goto out; } garp = 1; break; case NMRP_C_TFTP_UL_REQ: if (!upload_ok) { if (++ulreqs > 5) { printf("Bailing out after %d upload requests.\n", ulreqs); tx.msg.code = NMRP_C_CLOSE_REQ; break; } } else { if (verbosity) { printf("Ignoring extra upload request.\n"); } ethsock_set_timeout(sock, args->ul_timeout); tx.msg.code = NMRP_C_KEEP_ALIVE_REQ; break; } len = 0; filename = msg_opt_data(&rx.msg, NMRP_O_FILE_NAME, &len); if (filename) { if (!args->file_remote) { args->file_remote = filename; } printf("Received upload request: filename '%.*s'.\n", len, filename); } else if (!args->file_remote) { args->file_remote = args->file_local; printf("Received upload request with empty filename.\n"); } status = 0; if (args->tftpcmd) { printf("Executing '%s' ... \n", args->tftpcmd); setenv("IP", inet_ntoa(ipconf.addr), 1); setenv("MAC", mac_to_str(rx.eh.ether_shost), 1); setenv("NETMASK", inet_ntoa(ipconf.mask), 1); status = system(args->tftpcmd); } if (!status && args->file_local) { if (!autoip) { status = is_valid_ip(sock, &ipconf.addr, &ipconf.mask); if (status < 0) { goto out; } else if (!status) { printf("IP address of %s has changed. Please assign a " "static ip to the interface.\n", args->intf); tx.msg.code = NMRP_C_CLOSE_REQ; break; } } if (verbosity) { printf("Using remote filename '%s'.\n", args->file_remote); } if (!strcmp(args->file_local, "-")) { printf("Uploading from stdin ... "); } else { printf("Uploading %s ... ", leafname(args->file_local)); } fflush(stdout); status = tftp_put(args); } if (!status) { printf("OK\nWaiting for remote to respond.\n"); upload_ok = 1; ethsock_set_timeout(sock, args->ul_timeout); tx.msg.code = NMRP_C_KEEP_ALIVE_REQ; expect = NMRP_C_NONE; } else if (status == -2) { expect = NMRP_C_TFTP_UL_REQ; } else { goto out; } break; case NMRP_C_KEEP_ALIVE_REQ: tx.msg.code = NMRP_C_KEEP_ALIVE_ACK; ethsock_set_timeout(sock, args->ul_timeout); printf("Received keep-alive request.\n"); break; case NMRP_C_CLOSE_REQ: tx.msg.code = NMRP_C_CLOSE_ACK; break; case NMRP_C_CLOSE_ACK: status = 0; goto out; default: fprintf(stderr, "Unknown message code 0x%02x!\n", rx.msg.code); msg_dump(&rx.msg, 0); } if (tx.msg.code != NMRP_C_NONE) { msg_hton(&tx.msg); if (pkt_send(sock, &tx) < 0) { perror("sendto"); goto out; } if (tx.msg.code == NMRP_C_CLOSE_REQ) { goto out; } } if (rx.msg.code == NMRP_C_CLOSE_REQ) { printf("Remote finished. Closing connection.\n"); break; } status = pkt_recv(sock, &rx); if (status) { if (status == 2) { fprintf(stderr, "Timeout while waiting for %s.\n", msg_code_str(expect)); } goto out; } ethsock_set_timeout(sock, args->rx_timeout); } while (1); status = 0; if (ulreqs) { printf("Reboot your device now.\n"); } else { printf("No upload request received.\n"); } out: signal(SIGINT, sigh_orig); gsock = NULL; ethsock_arp_del(sock, arpmac, &arpip); ethsock_ip_del(sock, &gundo); ethsock_close(sock); return status; }