117680Spst/* 239300Sfenner * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 317680Spst * The Regents of the University of California. All rights reserved. 417680Spst * 517680Spst * Redistribution and use in source and binary forms, with or without 617680Spst * modification, are permitted provided that: (1) source code distributions 717680Spst * retain the above copyright notice and this paragraph in its entirety, (2) 817680Spst * distributions including binary code include the above copyright notice and 917680Spst * this paragraph in its entirety in the documentation or other materials 1017680Spst * provided with the distribution, and (3) all advertising materials mentioning 1117680Spst * features or use of this software display the following acknowledgement: 1217680Spst * ``This product includes software developed by the University of California, 1317680Spst * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 1417680Spst * the University nor the names of its contributors may be used to endorse 1517680Spst * or promote products derived from this software without specific prior 1617680Spst * written permission. 1717680Spst * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 1817680Spst * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 1917680Spst * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 2017680Spst * 2117680Spst * Format and print AppleTalk packets. 2256896Sfenner * 2356896Sfenner * $FreeBSD$ 2417680Spst */ 2526183Sfenner 2617680Spst#ifndef lint 27127675Sbmsstatic const char rcsid[] _U_ = 28190207Srpaulo "@(#) $Header: /tcpdump/master/tcpdump/print-atalk.c,v 1.81 2004-05-01 09:41:50 hannes Exp $ (LBL)"; 2917680Spst#endif 3017680Spst 3156896Sfenner#ifdef HAVE_CONFIG_H 3256896Sfenner#include "config.h" 3356896Sfenner#endif 3456896Sfenner 35127675Sbms#include <tcpdump-stdinc.h> 3617680Spst 3717680Spst#include <stdio.h> 3817680Spst#include <stdlib.h> 3917680Spst#include <string.h> 4098527Sfenner#include <pcap.h> 4117680Spst 4217680Spst#include "interface.h" 4317680Spst#include "addrtoname.h" 4417680Spst#include "ethertype.h" 4517680Spst#include "extract.h" /* must come after interface.h */ 4617680Spst#include "appletalk.h" 4717680Spst 4817680Spststatic struct tok type2str[] = { 4917680Spst { ddpRTMP, "rtmp" }, 5017680Spst { ddpRTMPrequest, "rtmpReq" }, 5117680Spst { ddpECHO, "echo" }, 5217680Spst { ddpIP, "IP" }, 5317680Spst { ddpARP, "ARP" }, 5417680Spst { ddpKLAP, "KLAP" }, 5517680Spst { 0, NULL } 5617680Spst}; 5717680Spst 5817680Spststruct aarp { 5975118Sfenner u_int16_t htype, ptype; 6075118Sfenner u_int8_t halen, palen; 6175118Sfenner u_int16_t op; 6275118Sfenner u_int8_t hsaddr[6]; 6375118Sfenner u_int8_t psaddr[4]; 6475118Sfenner u_int8_t hdaddr[6]; 6575118Sfenner u_int8_t pdaddr[4]; 6617680Spst}; 6717680Spst 6817680Spststatic char tstr[] = "[|atalk]"; 6917680Spst 7017680Spststatic void atp_print(const struct atATP *, u_int); 7117680Spststatic void atp_bitmap_print(u_char); 7217680Spststatic void nbp_print(const struct atNBP *, u_int, u_short, u_char, u_char); 7317680Spststatic const char *print_cstring(const char *, const u_char *); 7417680Spststatic const struct atNBPtuple *nbp_tuple_print(const struct atNBPtuple *, 7517680Spst const u_char *, 7617680Spst u_short, u_char, u_char); 7717680Spststatic const struct atNBPtuple *nbp_name_print(const struct atNBPtuple *, 7817680Spst const u_char *); 7917680Spststatic const char *ataddr_string(u_short, u_char); 8017680Spststatic void ddp_print(const u_char *, u_int, int, u_short, u_char, u_char); 8117680Spststatic const char *ddpskt_string(int); 8217680Spst 8317680Spst/* 8498527Sfenner * Print LLAP packets received on a physical LocalTalk interface. 8598527Sfenner */ 86127675Sbmsu_int 87127675Sbmsltalk_if_print(const struct pcap_pkthdr *h, const u_char *p) 8898527Sfenner{ 89127675Sbms return (llap_print(p, h->caplen)); 9098527Sfenner} 9198527Sfenner 9298527Sfenner/* 9375118Sfenner * Print AppleTalk LLAP packets. 9417680Spst */ 95127675Sbmsu_int 9675118Sfennerllap_print(register const u_char *bp, u_int length) 9717680Spst{ 9817680Spst register const struct LAP *lp; 9917680Spst register const struct atDDP *dp; 10017680Spst register const struct atShortDDP *sdp; 10117680Spst u_short snet; 102127675Sbms u_int hdrlen; 10317680Spst 104235530Sdelphij if (length < sizeof(*lp)) { 105235530Sdelphij (void)printf(" [|llap %u]", length); 106235530Sdelphij return (length); 107235530Sdelphij } 10898527Sfenner lp = (const struct LAP *)bp; 10917680Spst bp += sizeof(*lp); 11017680Spst length -= sizeof(*lp); 111127675Sbms hdrlen = sizeof(*lp); 11217680Spst switch (lp->type) { 11317680Spst 11417680Spst case lapShortDDP: 11517680Spst if (length < ddpSSize) { 116235530Sdelphij (void)printf(" [|sddp %u]", length); 117127675Sbms return (length); 11817680Spst } 11917680Spst sdp = (const struct atShortDDP *)bp; 12017680Spst printf("%s.%s", 12117680Spst ataddr_string(0, lp->src), ddpskt_string(sdp->srcSkt)); 12217680Spst printf(" > %s.%s:", 12317680Spst ataddr_string(0, lp->dst), ddpskt_string(sdp->dstSkt)); 12417680Spst bp += ddpSSize; 12517680Spst length -= ddpSSize; 126127675Sbms hdrlen += ddpSSize; 12717680Spst ddp_print(bp, length, sdp->type, 0, lp->src, sdp->srcSkt); 12817680Spst break; 12917680Spst 13017680Spst case lapDDP: 13117680Spst if (length < ddpSize) { 132235530Sdelphij (void)printf(" [|ddp %u]", length); 133127675Sbms return (length); 13417680Spst } 13517680Spst dp = (const struct atDDP *)bp; 13617680Spst snet = EXTRACT_16BITS(&dp->srcNet); 13717680Spst printf("%s.%s", ataddr_string(snet, dp->srcNode), 13817680Spst ddpskt_string(dp->srcSkt)); 13917680Spst printf(" > %s.%s:", 14017680Spst ataddr_string(EXTRACT_16BITS(&dp->dstNet), dp->dstNode), 14117680Spst ddpskt_string(dp->dstSkt)); 14217680Spst bp += ddpSize; 14317680Spst length -= ddpSize; 144127675Sbms hdrlen += ddpSize; 14517680Spst ddp_print(bp, length, dp->type, snet, dp->srcNode, dp->srcSkt); 14617680Spst break; 14717680Spst 14817680Spst#ifdef notdef 14917680Spst case lapKLAP: 15017680Spst klap_print(bp, length); 15117680Spst break; 15217680Spst#endif 15317680Spst 15417680Spst default: 155235530Sdelphij printf("%d > %d at-lap#%d %u", 15617680Spst lp->src, lp->dst, lp->type, length); 15717680Spst break; 15817680Spst } 159127675Sbms return (hdrlen); 16017680Spst} 16117680Spst 16275118Sfenner/* 16375118Sfenner * Print EtherTalk/TokenTalk packets (or FDDITalk, or whatever it's called 16475118Sfenner * when it runs over FDDI; yes, I've seen FDDI captures with AppleTalk 16575118Sfenner * packets in them). 16675118Sfenner */ 16775118Sfennervoid 16875118Sfenneratalk_print(register const u_char *bp, u_int length) 16975118Sfenner{ 17075118Sfenner register const struct atDDP *dp; 17175118Sfenner u_short snet; 17275118Sfenner 173146778Ssam if(!eflag) 174146778Ssam printf("AT "); 175146778Ssam 17675118Sfenner if (length < ddpSize) { 177235530Sdelphij (void)printf(" [|ddp %u]", length); 17898527Sfenner return; 17975118Sfenner } 18075118Sfenner dp = (const struct atDDP *)bp; 18175118Sfenner snet = EXTRACT_16BITS(&dp->srcNet); 18275118Sfenner printf("%s.%s", ataddr_string(snet, dp->srcNode), 18375118Sfenner ddpskt_string(dp->srcSkt)); 184146778Ssam printf(" > %s.%s: ", 18575118Sfenner ataddr_string(EXTRACT_16BITS(&dp->dstNet), dp->dstNode), 18675118Sfenner ddpskt_string(dp->dstSkt)); 18775118Sfenner bp += ddpSize; 18875118Sfenner length -= ddpSize; 18975118Sfenner ddp_print(bp, length, dp->type, snet, dp->srcNode, dp->srcSkt); 19075118Sfenner} 19175118Sfenner 19217680Spst/* XXX should probably pass in the snap header and do checks like arp_print() */ 19317680Spstvoid 19417680Spstaarp_print(register const u_char *bp, u_int length) 19517680Spst{ 19617680Spst register const struct aarp *ap; 19717680Spst 19817680Spst#define AT(member) ataddr_string((ap->member[1]<<8)|ap->member[2],ap->member[3]) 19917680Spst 20017680Spst printf("aarp "); 20117680Spst ap = (const struct aarp *)bp; 202127675Sbms if (EXTRACT_16BITS(&ap->htype) == 1 && 203127675Sbms EXTRACT_16BITS(&ap->ptype) == ETHERTYPE_ATALK && 20417680Spst ap->halen == 6 && ap->palen == 4 ) 205127675Sbms switch (EXTRACT_16BITS(&ap->op)) { 20617680Spst 20717680Spst case 1: /* request */ 20817680Spst (void)printf("who-has %s tell %s", 20917680Spst AT(pdaddr), AT(psaddr)); 21017680Spst return; 21117680Spst 21217680Spst case 2: /* response */ 21317680Spst (void)printf("reply %s is-at %s", 21417690Spst AT(psaddr), etheraddr_string(ap->hsaddr)); 21517680Spst return; 21617680Spst 21717680Spst case 3: /* probe (oy!) */ 21817680Spst (void)printf("probe %s tell %s", 21917680Spst AT(pdaddr), AT(psaddr)); 22017680Spst return; 22117680Spst } 22275118Sfenner (void)printf("len %u op %u htype %u ptype %#x halen %u palen %u", 223127675Sbms length, EXTRACT_16BITS(&ap->op), EXTRACT_16BITS(&ap->htype), 224127675Sbms EXTRACT_16BITS(&ap->ptype), ap->halen, ap->palen); 22517680Spst} 22617680Spst 22775118Sfenner/* 22875118Sfenner * Print AppleTalk Datagram Delivery Protocol packets. 22975118Sfenner */ 23017680Spststatic void 23117680Spstddp_print(register const u_char *bp, register u_int length, register int t, 23217680Spst register u_short snet, register u_char snode, u_char skt) 23317680Spst{ 23417680Spst 23517680Spst switch (t) { 23617680Spst 23717680Spst case ddpNBP: 23817680Spst nbp_print((const struct atNBP *)bp, length, snet, snode, skt); 23917680Spst break; 24017680Spst 24117680Spst case ddpATP: 24217680Spst atp_print((const struct atATP *)bp, length); 24317680Spst break; 24417680Spst 245146778Ssam case ddpEIGRP: 246146778Ssam eigrp_print(bp, length); 247146778Ssam break; 248146778Ssam 24917680Spst default: 25017680Spst (void)printf(" at-%s %d", tok2str(type2str, NULL, t), length); 25117680Spst break; 25217680Spst } 25317680Spst} 25417680Spst 25517680Spststatic void 25617680Spstatp_print(register const struct atATP *ap, u_int length) 25717680Spst{ 25817680Spst char c; 25917680Spst u_int32_t data; 26017680Spst 26117680Spst if ((const u_char *)(ap + 1) > snapend) { 26217680Spst /* Just bail if we don't have the whole chunk. */ 26317680Spst fputs(tstr, stdout); 26417680Spst return; 26517680Spst } 266235530Sdelphij if (length < sizeof(*ap)) { 267235530Sdelphij (void)printf(" [|atp %u]", length); 268235530Sdelphij return; 269235530Sdelphij } 27017680Spst length -= sizeof(*ap); 27117680Spst switch (ap->control & 0xc0) { 27217680Spst 27317680Spst case atpReqCode: 27417680Spst (void)printf(" atp-req%s %d", 27517680Spst ap->control & atpXO? " " : "*", 27617680Spst EXTRACT_16BITS(&ap->transID)); 27717680Spst 27817680Spst atp_bitmap_print(ap->bitmap); 27917680Spst 28017680Spst if (length != 0) 281235530Sdelphij (void)printf(" [len=%u]", length); 28217680Spst 28317680Spst switch (ap->control & (atpEOM|atpSTS)) { 28417680Spst case atpEOM: 28517680Spst (void)printf(" [EOM]"); 28617680Spst break; 28717680Spst case atpSTS: 28817680Spst (void)printf(" [STS]"); 28917680Spst break; 29017680Spst case atpEOM|atpSTS: 29117680Spst (void)printf(" [EOM,STS]"); 29217680Spst break; 29317680Spst } 29417680Spst break; 29517680Spst 29617680Spst case atpRspCode: 297235530Sdelphij (void)printf(" atp-resp%s%d:%d (%u)", 29817680Spst ap->control & atpEOM? "*" : " ", 29917680Spst EXTRACT_16BITS(&ap->transID), ap->bitmap, length); 30017680Spst switch (ap->control & (atpXO|atpSTS)) { 30117680Spst case atpXO: 30217680Spst (void)printf(" [XO]"); 30317680Spst break; 30417680Spst case atpSTS: 30517680Spst (void)printf(" [STS]"); 30617680Spst break; 30717680Spst case atpXO|atpSTS: 30817680Spst (void)printf(" [XO,STS]"); 30917680Spst break; 31017680Spst } 31117680Spst break; 31217680Spst 31317680Spst case atpRelCode: 31417680Spst (void)printf(" atp-rel %d", EXTRACT_16BITS(&ap->transID)); 31517680Spst 31617680Spst atp_bitmap_print(ap->bitmap); 31717680Spst 31817680Spst /* length should be zero */ 31917680Spst if (length) 320235530Sdelphij (void)printf(" [len=%u]", length); 32117680Spst 32217680Spst /* there shouldn't be any control flags */ 32317680Spst if (ap->control & (atpXO|atpEOM|atpSTS)) { 32417680Spst c = '['; 32517680Spst if (ap->control & atpXO) { 32617680Spst (void)printf("%cXO", c); 32717680Spst c = ','; 32817680Spst } 32917680Spst if (ap->control & atpEOM) { 33017680Spst (void)printf("%cEOM", c); 33117680Spst c = ','; 33217680Spst } 33317680Spst if (ap->control & atpSTS) { 33417680Spst (void)printf("%cSTS", c); 33517680Spst c = ','; 33617680Spst } 33717680Spst (void)printf("]"); 33817680Spst } 33917680Spst break; 34017680Spst 34117680Spst default: 342235530Sdelphij (void)printf(" atp-0x%x %d (%u)", ap->control, 34317680Spst EXTRACT_16BITS(&ap->transID), length); 34417680Spst break; 34517680Spst } 34617680Spst data = EXTRACT_32BITS(&ap->userData); 34717680Spst if (data != 0) 34817680Spst (void)printf(" 0x%x", data); 34917680Spst} 35017680Spst 35117680Spststatic void 35217680Spstatp_bitmap_print(register u_char bm) 35317680Spst{ 35417680Spst register char c; 35517680Spst register int i; 35617680Spst 35717680Spst /* 35817680Spst * The '& 0xff' below is needed for compilers that want to sign 35917680Spst * extend a u_char, which is the case with the Ultrix compiler. 36017680Spst * (gcc is smart enough to eliminate it, at least on the Sparc). 36117680Spst */ 36217680Spst if ((bm + 1) & (bm & 0xff)) { 36317680Spst c = '<'; 36417680Spst for (i = 0; bm; ++i) { 36517680Spst if (bm & 1) { 36617680Spst (void)printf("%c%d", c, i); 36717680Spst c = ','; 36817680Spst } 36917680Spst bm >>= 1; 37017680Spst } 37117680Spst (void)printf(">"); 37217680Spst } else { 37317680Spst for (i = 0; bm; ++i) 37417680Spst bm >>= 1; 37517680Spst if (i > 1) 37617680Spst (void)printf("<0-%d>", i - 1); 37717680Spst else 37817680Spst (void)printf("<0>"); 37917680Spst } 38017680Spst} 38117680Spst 38217680Spststatic void 38317680Spstnbp_print(register const struct atNBP *np, u_int length, register u_short snet, 38417680Spst register u_char snode, register u_char skt) 38517680Spst{ 38617680Spst register const struct atNBPtuple *tp = 38798527Sfenner (const struct atNBPtuple *)((u_char *)np + nbpHeaderSize); 38817680Spst int i; 38917680Spst const u_char *ep; 39017680Spst 391111729Sfenner if (length < nbpHeaderSize) { 392235530Sdelphij (void)printf(" truncated-nbp %u", length); 393111729Sfenner return; 394111729Sfenner } 395111729Sfenner 39617680Spst length -= nbpHeaderSize; 39717680Spst if (length < 8) { 39817680Spst /* must be room for at least one tuple */ 399235530Sdelphij (void)printf(" truncated-nbp %u", length + nbpHeaderSize); 40017680Spst return; 40117680Spst } 40217680Spst /* ep points to end of available data */ 40317680Spst ep = snapend; 40417680Spst if ((const u_char *)tp > ep) { 40517680Spst fputs(tstr, stdout); 40617680Spst return; 40717680Spst } 40817680Spst switch (i = np->control & 0xf0) { 40917680Spst 41017680Spst case nbpBrRq: 41117680Spst case nbpLkUp: 41217680Spst (void)printf(i == nbpLkUp? " nbp-lkup %d:":" nbp-brRq %d:", 41317680Spst np->id); 41417680Spst if ((const u_char *)(tp + 1) > ep) { 41517680Spst fputs(tstr, stdout); 41617680Spst return; 41717680Spst } 41817680Spst (void)nbp_name_print(tp, ep); 41917680Spst /* 42017680Spst * look for anomalies: the spec says there can only 42117680Spst * be one tuple, the address must match the source 42217680Spst * address and the enumerator should be zero. 42317680Spst */ 42417680Spst if ((np->control & 0xf) != 1) 42517680Spst (void)printf(" [ntup=%d]", np->control & 0xf); 42617680Spst if (tp->enumerator) 42717680Spst (void)printf(" [enum=%d]", tp->enumerator); 42817680Spst if (EXTRACT_16BITS(&tp->net) != snet || 42917680Spst tp->node != snode || tp->skt != skt) 43017680Spst (void)printf(" [addr=%s.%d]", 43117680Spst ataddr_string(EXTRACT_16BITS(&tp->net), 43217680Spst tp->node), tp->skt); 43317680Spst break; 43417680Spst 43517680Spst case nbpLkUpReply: 43617680Spst (void)printf(" nbp-reply %d:", np->id); 43717680Spst 43817680Spst /* print each of the tuples in the reply */ 43917680Spst for (i = np->control & 0xf; --i >= 0 && tp; ) 44017680Spst tp = nbp_tuple_print(tp, ep, snet, snode, skt); 44117680Spst break; 44217680Spst 44317680Spst default: 444235530Sdelphij (void)printf(" nbp-0x%x %d (%u)", np->control, np->id, 44517680Spst length); 44617680Spst break; 44717680Spst } 44817680Spst} 44917680Spst 45017680Spst/* print a counted string */ 45117680Spststatic const char * 45217680Spstprint_cstring(register const char *cp, register const u_char *ep) 45317680Spst{ 45417680Spst register u_int length; 45517680Spst 45617680Spst if (cp >= (const char *)ep) { 45717680Spst fputs(tstr, stdout); 45817680Spst return (0); 45917680Spst } 46017680Spst length = *cp++; 46117680Spst 46217680Spst /* Spec says string can be at most 32 bytes long */ 46339300Sfenner if (length > 32) { 46439300Sfenner (void)printf("[len=%u]", length); 46517680Spst return (0); 46617680Spst } 46739300Sfenner while ((int)--length >= 0) { 46898527Sfenner if (cp >= (const char *)ep) { 46917680Spst fputs(tstr, stdout); 47017680Spst return (0); 47117680Spst } 47217680Spst putchar(*cp++); 47317680Spst } 47417680Spst return (cp); 47517680Spst} 47617680Spst 47717680Spststatic const struct atNBPtuple * 47817680Spstnbp_tuple_print(register const struct atNBPtuple *tp, 47917680Spst register const u_char *ep, 48017680Spst register u_short snet, register u_char snode, 48117680Spst register u_char skt) 48217680Spst{ 48317680Spst register const struct atNBPtuple *tpn; 48417680Spst 48517680Spst if ((const u_char *)(tp + 1) > ep) { 48617680Spst fputs(tstr, stdout); 48717680Spst return 0; 48817680Spst } 48917680Spst tpn = nbp_name_print(tp, ep); 49017680Spst 49117680Spst /* if the enumerator isn't 1, print it */ 49217680Spst if (tp->enumerator != 1) 49317680Spst (void)printf("(%d)", tp->enumerator); 49417680Spst 49517680Spst /* if the socket doesn't match the src socket, print it */ 49617680Spst if (tp->skt != skt) 49717680Spst (void)printf(" %d", tp->skt); 49817680Spst 49917680Spst /* if the address doesn't match the src address, it's an anomaly */ 50017680Spst if (EXTRACT_16BITS(&tp->net) != snet || tp->node != snode) 50117680Spst (void)printf(" [addr=%s]", 50217680Spst ataddr_string(EXTRACT_16BITS(&tp->net), tp->node)); 50317680Spst 50417680Spst return (tpn); 50517680Spst} 50617680Spst 50717680Spststatic const struct atNBPtuple * 50817680Spstnbp_name_print(const struct atNBPtuple *tp, register const u_char *ep) 50917680Spst{ 51017680Spst register const char *cp = (const char *)tp + nbpTupleSize; 51117680Spst 51217680Spst putchar(' '); 51317680Spst 51417680Spst /* Object */ 51517680Spst putchar('"'); 51617680Spst if ((cp = print_cstring(cp, ep)) != NULL) { 51717680Spst /* Type */ 51817680Spst putchar(':'); 51917680Spst if ((cp = print_cstring(cp, ep)) != NULL) { 52017680Spst /* Zone */ 52117680Spst putchar('@'); 52217680Spst if ((cp = print_cstring(cp, ep)) != NULL) 52317680Spst putchar('"'); 52417680Spst } 52517680Spst } 52617680Spst return ((const struct atNBPtuple *)cp); 52717680Spst} 52817680Spst 52917680Spst 53017680Spst#define HASHNAMESIZE 4096 53117680Spst 53217680Spststruct hnamemem { 53317680Spst int addr; 53417680Spst char *name; 53517680Spst struct hnamemem *nxt; 53617680Spst}; 53717680Spst 53817680Spststatic struct hnamemem hnametable[HASHNAMESIZE]; 53917680Spst 54017680Spststatic const char * 54117680Spstataddr_string(u_short atnet, u_char athost) 54217680Spst{ 54317680Spst register struct hnamemem *tp, *tp2; 54417680Spst register int i = (atnet << 8) | athost; 54566644Skris char nambuf[MAXHOSTNAMELEN + 20]; 54617680Spst static int first = 1; 54717680Spst FILE *fp; 54817680Spst 54917680Spst /* 55017680Spst * if this is the first call, see if there's an AppleTalk 55117680Spst * number to name map file. 55217680Spst */ 55317680Spst if (first && (first = 0, !nflag) 55417680Spst && (fp = fopen("/etc/atalk.names", "r"))) { 55517680Spst char line[256]; 556235530Sdelphij int i1, i2; 55717680Spst 55817680Spst while (fgets(line, sizeof(line), fp)) { 55917680Spst if (line[0] == '\n' || line[0] == 0 || line[0] == '#') 56017680Spst continue; 561235530Sdelphij if (sscanf(line, "%d.%d %256s", &i1, &i2, nambuf) == 3) 56217680Spst /* got a hostname. */ 563235530Sdelphij i2 |= (i1 << 8); 564235530Sdelphij else if (sscanf(line, "%d %256s", &i1, nambuf) == 2) 56517680Spst /* got a net name */ 566235530Sdelphij i2 = (i1 << 8) | 255; 56717680Spst else 56817680Spst continue; 56917680Spst 57018241Spst for (tp = &hnametable[i2 & (HASHNAMESIZE-1)]; 57117680Spst tp->nxt; tp = tp->nxt) 57217680Spst ; 57318241Spst tp->addr = i2; 57417680Spst tp->nxt = newhnamemem(); 57598527Sfenner tp->name = strdup(nambuf); 57617680Spst } 57717680Spst fclose(fp); 57817680Spst } 57917680Spst 58017680Spst for (tp = &hnametable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt) 58117680Spst if (tp->addr == i) 58217680Spst return (tp->name); 58317680Spst 58417680Spst /* didn't have the node name -- see if we've got the net name */ 58517680Spst i |= 255; 58617680Spst for (tp2 = &hnametable[i & (HASHNAMESIZE-1)]; tp2->nxt; tp2 = tp2->nxt) 58717680Spst if (tp2->addr == i) { 58817680Spst tp->addr = (atnet << 8) | athost; 58917680Spst tp->nxt = newhnamemem(); 59075118Sfenner (void)snprintf(nambuf, sizeof(nambuf), "%s.%d", 59175118Sfenner tp2->name, athost); 59298527Sfenner tp->name = strdup(nambuf); 59317680Spst return (tp->name); 59417680Spst } 59517680Spst 59617680Spst tp->addr = (atnet << 8) | athost; 59717680Spst tp->nxt = newhnamemem(); 59817680Spst if (athost != 255) 599235530Sdelphij (void)snprintf(nambuf, sizeof(nambuf), "%d.%d", atnet, athost); 60017680Spst else 601235530Sdelphij (void)snprintf(nambuf, sizeof(nambuf), "%d", atnet); 60298527Sfenner tp->name = strdup(nambuf); 60317680Spst 60417680Spst return (tp->name); 60517680Spst} 60617680Spst 60717680Spststatic struct tok skt2str[] = { 60817680Spst { rtmpSkt, "rtmp" }, /* routing table maintenance */ 60917680Spst { nbpSkt, "nis" }, /* name info socket */ 61017680Spst { echoSkt, "echo" }, /* AppleTalk echo protocol */ 61117680Spst { zipSkt, "zip" }, /* zone info protocol */ 61217680Spst { 0, NULL } 61317680Spst}; 61417680Spst 61517680Spststatic const char * 61617680Spstddpskt_string(register int skt) 61717680Spst{ 61817680Spst static char buf[8]; 61917680Spst 62017680Spst if (nflag) { 62175118Sfenner (void)snprintf(buf, sizeof(buf), "%d", skt); 62217680Spst return (buf); 62317680Spst } 62417680Spst return (tok2str(skt2str, "%d", skt)); 62517680Spst} 626