121811Skarels /* 221811Skarels * Copyright (c) 1983 Regents of the University of California. 334941Sbostic * All rights reserved. 434941Sbostic * 534941Sbostic * Redistribution and use in source and binary forms are permitted 634941Sbostic * provided that the above copyright notice and this paragraph are 734941Sbostic * duplicated in all such forms and that any documentation, 834941Sbostic * advertising materials, and other materials related to such 934941Sbostic * distribution and use acknowledge that the software was developed 1034941Sbostic * by the University of California, Berkeley. The name of the 1134941Sbostic * University may not be used to endorse or promote products derived 1234941Sbostic * from this software without specific prior written permission. 1334941Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1434941Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1534941Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1621811Skarels */ 1721811Skarels 1814869Ssam #ifndef lint 1921811Skarels char copyright[] = 2021811Skarels "@(#) Copyright (c) 1983 Regents of the University of California.\n\ 2121811Skarels All rights reserved.\n"; 2234941Sbostic #endif /* not lint */ 2314869Ssam 2421811Skarels #ifndef lint 25*37227Ssklower static char sccsid[] = "@(#)ifconfig.c 4.22 (Berkeley) 03/23/89"; 2634941Sbostic #endif /* not lint */ 2721811Skarels 2814869Ssam #include <sys/types.h> 2914869Ssam #include <sys/socket.h> 3014869Ssam #include <sys/ioctl.h> 3114869Ssam 3222485Ssklower #include <net/if.h> 3314869Ssam #include <netinet/in.h> 3414869Ssam 3522485Ssklower #define NSIP 3622485Ssklower #include <netns/ns.h> 3722485Ssklower #include <netns/ns_if.h> 3822485Ssklower 3914869Ssam #include <stdio.h> 4014869Ssam #include <errno.h> 4114869Ssam #include <ctype.h> 4214869Ssam #include <netdb.h> 4314869Ssam 4422485Ssklower extern int errno; 4514869Ssam struct ifreq ifr; 46*37227Ssklower struct sockaddr_in sin = { sizeof(sin), AF_INET }; 4721811Skarels struct sockaddr_in broadaddr; 48*37227Ssklower struct sockaddr_in netmask = {sizeof(sin), AF_INET }; 49*37227Ssklower struct sockaddr_in ipdst = {sizeof(sin), AF_INET }; 5014869Ssam char name[30]; 5121811Skarels int flags; 5226185Skarels int metric; 5316329Skarels int setaddr; 5421811Skarels int setmask; 5521811Skarels int setbroadaddr; 5622485Ssklower int setipdst; 5714869Ssam int s; 5821811Skarels extern int errno; 5914869Ssam 6021811Skarels int setifflags(), setifaddr(), setifdstaddr(), setifnetmask(); 6126185Skarels int setifmetric(), setifbroadaddr(), setifipdst(); 6214869Ssam 6321811Skarels #define NEXTARG 0xffffff 6421811Skarels 6514869Ssam struct cmd { 6614869Ssam char *c_name; 6721811Skarels int c_parameter; /* NEXTARG means next argv */ 6814869Ssam int (*c_func)(); 6914869Ssam } cmds[] = { 7014869Ssam { "up", IFF_UP, setifflags } , 7114869Ssam { "down", -IFF_UP, setifflags }, 7214869Ssam { "trailers", -IFF_NOTRAILERS,setifflags }, 7314869Ssam { "-trailers", IFF_NOTRAILERS, setifflags }, 7415359Skarels { "arp", -IFF_NOARP, setifflags }, 7515359Skarels { "-arp", IFF_NOARP, setifflags }, 7615286Sleres { "debug", IFF_DEBUG, setifflags }, 7715286Sleres { "-debug", -IFF_DEBUG, setifflags }, 7815004Ssam #ifdef notdef 7921811Skarels #define EN_SWABIPS 0x1000 8015004Ssam { "swabips", EN_SWABIPS, setifflags }, 8115004Ssam { "-swabips", -EN_SWABIPS, setifflags }, 8215004Ssam #endif 8321811Skarels { "netmask", NEXTARG, setifnetmask }, 8426185Skarels { "metric", NEXTARG, setifmetric }, 8521811Skarels { "broadcast", NEXTARG, setifbroadaddr }, 8622485Ssklower { "ipdst", NEXTARG, setifipdst }, 8714869Ssam { 0, 0, setifaddr }, 8817218Stef { 0, 0, setifdstaddr }, 8914869Ssam }; 9014869Ssam 9122485Ssklower /* 9222485Ssklower * XNS support liberally adapted from 9322485Ssklower * code written at the University of Maryland 9422485Ssklower * principally by James O'Toole and Chris Torek. 9522485Ssklower */ 9622485Ssklower 9722485Ssklower int in_status(), in_getaddr(); 9822485Ssklower int xns_status(), xns_getaddr(); 9922485Ssklower 10022485Ssklower /* Known address families */ 10122485Ssklower struct afswtch { 10222485Ssklower char *af_name; 10322485Ssklower short af_af; 10422485Ssklower int (*af_status)(); 10522485Ssklower int (*af_getaddr)(); 10622485Ssklower } afs[] = { 10722485Ssklower { "inet", AF_INET, in_status, in_getaddr }, 10822485Ssklower { "ns", AF_NS, xns_status, xns_getaddr }, 10922485Ssklower { 0, 0, 0, 0 } 11022485Ssklower }; 11122485Ssklower 11222485Ssklower struct afswtch *afp; /*the address family being set or asked about*/ 11322485Ssklower 11414869Ssam main(argc, argv) 11514869Ssam int argc; 11614869Ssam char *argv[]; 11714869Ssam { 11822485Ssklower int af = AF_INET; 11927061Skarels 12014869Ssam if (argc < 2) { 12130789Sbostic fprintf(stderr, "usage: ifconfig interface\n%s%s%s%s%s", 12226185Skarels "\t[ af [ address [ dest_addr ] ] [ up ] [ down ]", 12326185Skarels "[ netmask mask ] ]\n", 12426185Skarels "\t[ metric n ]\n", 12526185Skarels "\t[ trailers | -trailers ]\n", 12626185Skarels "\t[ arp | -arp ]\n"); 12714869Ssam exit(1); 12814869Ssam } 12922485Ssklower argc--, argv++; 13024248Ssklower strncpy(name, *argv, sizeof(name)); 13122485Ssklower strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); 13222485Ssklower argc--, argv++; 13322485Ssklower if (argc > 0) { 13422485Ssklower struct afswtch *myafp; 13522485Ssklower 13622485Ssklower for (myafp = afp = afs; myafp->af_name; myafp++) 13722485Ssklower if (strcmp(myafp->af_name, *argv) == 0) { 13822485Ssklower afp = myafp; argc--; argv++; 13922485Ssklower break; 14022485Ssklower } 14122485Ssklower af = ifr.ifr_addr.sa_family = afp->af_af; 14222485Ssklower } 14322485Ssklower s = socket(af, SOCK_DGRAM, 0); 14414869Ssam if (s < 0) { 14514869Ssam perror("ifconfig: socket"); 14614869Ssam exit(1); 14714869Ssam } 14814869Ssam if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) { 14914869Ssam Perror("ioctl (SIOCGIFFLAGS)"); 15014869Ssam exit(1); 15114869Ssam } 15222485Ssklower strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name); 15321811Skarels flags = ifr.ifr_flags; 15426185Skarels if (ioctl(s, SIOCGIFMETRIC, (caddr_t)&ifr) < 0) 15526185Skarels perror("ioctl (SIOCGIFMETRIC)"); 15626185Skarels else 15726185Skarels metric = ifr.ifr_metric; 15814869Ssam if (argc == 0) { 15914869Ssam status(); 16014869Ssam exit(0); 16114869Ssam } 16214869Ssam while (argc > 0) { 16314869Ssam register struct cmd *p; 16414869Ssam 16514869Ssam for (p = cmds; p->c_name; p++) 16614869Ssam if (strcmp(*argv, p->c_name) == 0) 16714869Ssam break; 16817218Stef if (p->c_name == 0 && setaddr) 16917218Stef p++; /* got src, do dst */ 17021811Skarels if (p->c_func) { 17121811Skarels if (p->c_parameter == NEXTARG) { 17221811Skarels (*p->c_func)(argv[1]); 17321811Skarels argc--, argv++; 17421811Skarels } else 17521811Skarels (*p->c_func)(*argv, p->c_parameter); 17621811Skarels } 17714869Ssam argc--, argv++; 17814869Ssam } 17927061Skarels if ((setmask || setaddr) && (af == AF_INET)) { 18021811Skarels /* 18121811Skarels * If setting the address and not the mask, 18221811Skarels * clear any existing mask and the kernel will then 18321811Skarels * assign the default. If setting both, 18421811Skarels * set the mask first, so the address will be 18521811Skarels * interpreted correctly. 18621811Skarels */ 18721811Skarels ifr.ifr_addr = *(struct sockaddr *)&netmask; 18821811Skarels if (ioctl(s, SIOCSIFNETMASK, (caddr_t)&ifr) < 0) 18921811Skarels Perror("ioctl (SIOCSIFNETMASK)"); 19021811Skarels } 19122485Ssklower if (setipdst && af==AF_NS) { 19222485Ssklower struct nsip_req rq; 19322485Ssklower int size = sizeof(rq); 19422485Ssklower 19522485Ssklower rq.rq_ns = *(struct sockaddr *) &sin; 19622485Ssklower rq.rq_ip = *(struct sockaddr *) &ipdst; 19722485Ssklower 19822485Ssklower if (setsockopt(s, 0, SO_NSIP_ROUTE, &rq, size) < 0) 19922485Ssklower Perror("Encapsulation Routing"); 20022485Ssklower setaddr = 0; 20122485Ssklower } 20216329Skarels if (setaddr) { 20316329Skarels ifr.ifr_addr = *(struct sockaddr *) &sin; 20416329Skarels if (ioctl(s, SIOCSIFADDR, (caddr_t)&ifr) < 0) 20516329Skarels Perror("ioctl (SIOCSIFADDR)"); 20616329Skarels } 20721811Skarels if (setbroadaddr) { 20821811Skarels ifr.ifr_addr = *(struct sockaddr *)&broadaddr; 20921811Skarels if (ioctl(s, SIOCSIFBRDADDR, (caddr_t)&ifr) < 0) 21021811Skarels Perror("ioctl (SIOCSIFBRDADDR)"); 21121811Skarels } 21214869Ssam exit(0); 21314869Ssam } 21414869Ssam 21514869Ssam /*ARGSUSED*/ 21614869Ssam setifaddr(addr, param) 21714869Ssam char *addr; 21822485Ssklower short param; 21914869Ssam { 22016329Skarels /* 22116329Skarels * Delay the ioctl to set the interface addr until flags are all set. 22216329Skarels * The address interpretation may depend on the flags, 22316329Skarels * and the flags may change when the address is set. 22415390Skarels */ 22516329Skarels setaddr++; 22622485Ssklower (*afp->af_getaddr)(addr, &sin); 22714869Ssam } 22814869Ssam 22921811Skarels setifnetmask(addr) 23021811Skarels char *addr; 23121811Skarels { 23222485Ssklower in_getaddr(addr, &netmask); 23321811Skarels setmask++; 23421811Skarels } 23521811Skarels 23621811Skarels setifbroadaddr(addr) 23721811Skarels char *addr; 23821811Skarels { 23922485Ssklower (*afp->af_getaddr)(addr, &broadaddr); 24021811Skarels setbroadaddr++; 24121811Skarels } 24221811Skarels 24322485Ssklower setifipdst(addr) 24422485Ssklower char *addr; 24522485Ssklower { 24622485Ssklower in_getaddr(addr, &ipdst); 24722485Ssklower setipdst++; 24822485Ssklower } 24922485Ssklower 25017218Stef /*ARGSUSED*/ 25117218Stef setifdstaddr(addr, param) 25217218Stef char *addr; 25317218Stef int param; 25417218Stef { 25517218Stef 25622485Ssklower (*afp->af_getaddr)(addr, &ifr.ifr_addr); 25717218Stef if (ioctl(s, SIOCSIFDSTADDR, (caddr_t)&ifr) < 0) 25817218Stef Perror("ioctl (SIOCSIFDSTADDR)"); 25917218Stef } 26017218Stef 26114870Ssam setifflags(vname, value) 26214870Ssam char *vname; 26322485Ssklower short value; 26414869Ssam { 26522485Ssklower if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) { 26622485Ssklower Perror("ioctl (SIOCGIFFLAGS)"); 26722485Ssklower exit(1); 26822485Ssklower } 26922485Ssklower strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); 27022485Ssklower flags = ifr.ifr_flags; 27114869Ssam 27214869Ssam if (value < 0) { 27314869Ssam value = -value; 27421811Skarels flags &= ~value; 27514869Ssam } else 27621811Skarels flags |= value; 27721811Skarels ifr.ifr_flags = flags; 27814869Ssam if (ioctl(s, SIOCSIFFLAGS, (caddr_t)&ifr) < 0) 27914870Ssam Perror(vname); 28014869Ssam } 28114869Ssam 28226185Skarels setifmetric(val) 28326185Skarels char *val; 28426185Skarels { 28526185Skarels strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); 28626185Skarels ifr.ifr_metric = atoi(val); 28726185Skarels if (ioctl(s, SIOCSIFMETRIC, (caddr_t)&ifr) < 0) 28826185Skarels perror("ioctl (set metric)"); 28926185Skarels } 29026185Skarels 29126185Skarels #define IFFBITS \ 29226185Skarels "\020\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT\6NOTRAILERS\7RUNNING\10NOARP\ 29326185Skarels " 29426185Skarels 29522485Ssklower /* 29622485Ssklower * Print the status of the interface. If an address family was 29722485Ssklower * specified, show it and it only; otherwise, show them all. 29822485Ssklower */ 29914869Ssam status() 30014869Ssam { 30122485Ssklower register struct afswtch *p = afp; 30222485Ssklower short af = ifr.ifr_addr.sa_family; 30322485Ssklower 30426185Skarels printf("%s: ", name); 30526185Skarels printb("flags", flags, IFFBITS); 30626185Skarels if (metric) 30726185Skarels printf(" metric %d", metric); 30826185Skarels putchar('\n'); 30922485Ssklower if ((p = afp) != NULL) { 31028468Skarels (*p->af_status)(1); 31128468Skarels } else for (p = afs; p->af_name; p++) { 31222485Ssklower ifr.ifr_addr.sa_family = p->af_af; 31328468Skarels (*p->af_status)(0); 31422485Ssklower } 31522485Ssklower } 31622485Ssklower 31728468Skarels in_status(force) 31828468Skarels int force; 31922485Ssklower { 32014869Ssam struct sockaddr_in *sin; 32122485Ssklower char *inet_ntoa(); 32214869Ssam 32327061Skarels strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); 32421811Skarels if (ioctl(s, SIOCGIFADDR, (caddr_t)&ifr) < 0) { 32528468Skarels if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT) { 32628468Skarels if (!force) 32728468Skarels return; 32821811Skarels bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr)); 32928468Skarels } else 33028468Skarels perror("ioctl (SIOCGIFADDR)"); 33121811Skarels } 33214869Ssam sin = (struct sockaddr_in *)&ifr.ifr_addr; 33326429Skarels printf("\tinet %s ", inet_ntoa(sin->sin_addr)); 33428468Skarels strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); 33528468Skarels if (ioctl(s, SIOCGIFNETMASK, (caddr_t)&ifr) < 0) { 33628468Skarels if (errno != EADDRNOTAVAIL) 33728468Skarels perror("ioctl (SIOCGIFNETMASK)"); 33828468Skarels bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr)); 33928468Skarels } else 34028468Skarels netmask.sin_addr = 34128468Skarels ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr; 34217218Stef if (flags & IFF_POINTOPOINT) { 34321811Skarels if (ioctl(s, SIOCGIFDSTADDR, (caddr_t)&ifr) < 0) { 34421811Skarels if (errno == EADDRNOTAVAIL) 34521811Skarels bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr)); 34621811Skarels else 34728468Skarels perror("ioctl (SIOCGIFDSTADDR)"); 34821811Skarels } 34922485Ssklower strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); 35017218Stef sin = (struct sockaddr_in *)&ifr.ifr_dstaddr; 35117218Stef printf("--> %s ", inet_ntoa(sin->sin_addr)); 35217218Stef } 35321811Skarels printf("netmask %x ", ntohl(netmask.sin_addr.s_addr)); 35421811Skarels if (flags & IFF_BROADCAST) { 35521811Skarels if (ioctl(s, SIOCGIFBRDADDR, (caddr_t)&ifr) < 0) { 35621811Skarels if (errno == EADDRNOTAVAIL) 35728468Skarels bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr)); 35828468Skarels else 35928468Skarels perror("ioctl (SIOCGIFADDR)"); 36021811Skarels } 36122485Ssklower strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); 36221811Skarels sin = (struct sockaddr_in *)&ifr.ifr_addr; 36328468Skarels if (sin->sin_addr.s_addr != 0) 36428468Skarels printf("broadcast %s", inet_ntoa(sin->sin_addr)); 36521811Skarels } 36626185Skarels putchar('\n'); 36714869Ssam } 36814869Ssam 36922485Ssklower 37028468Skarels xns_status(force) 37128468Skarels int force; 37222485Ssklower { 37322485Ssklower struct sockaddr_ns *sns; 37422485Ssklower 37522485Ssklower close(s); 37622485Ssklower s = socket(AF_NS, SOCK_DGRAM, 0); 37722485Ssklower if (s < 0) { 37830692Smckusick if (errno == EPROTONOSUPPORT) 37924248Ssklower return; 38022485Ssklower perror("ifconfig: socket"); 38122485Ssklower exit(1); 38222485Ssklower } 38322485Ssklower if (ioctl(s, SIOCGIFADDR, (caddr_t)&ifr) < 0) { 38428468Skarels if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT) { 38528468Skarels if (!force) 38628468Skarels return; 38728468Skarels bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr)); 38828468Skarels } else 38928468Skarels perror("ioctl (SIOCGIFADDR)"); 39022485Ssklower } 39122485Ssklower strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name); 39222485Ssklower sns = (struct sockaddr_ns *)&ifr.ifr_addr; 39326185Skarels printf("\tns %s ", ns_ntoa(sns->sns_addr)); 39426101Ssklower if (flags & IFF_POINTOPOINT) { /* by W. Nesheim@Cornell */ 39526101Ssklower if (ioctl(s, SIOCGIFDSTADDR, (caddr_t)&ifr) < 0) { 39626101Ssklower if (errno == EADDRNOTAVAIL) 39726101Ssklower bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr)); 39826101Ssklower else 39926101Ssklower Perror("ioctl (SIOCGIFDSTADDR)"); 40026101Ssklower } 40126101Ssklower strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); 40226101Ssklower sns = (struct sockaddr_ns *)&ifr.ifr_dstaddr; 40326101Ssklower printf("--> %s ", ns_ntoa(sns->sns_addr)); 40426101Ssklower } 40522485Ssklower putchar('\n'); 40622485Ssklower } 40722485Ssklower 40814869Ssam Perror(cmd) 40914869Ssam char *cmd; 41014869Ssam { 41114869Ssam extern int errno; 41214869Ssam 41314869Ssam fprintf(stderr, "ifconfig: "); 41414869Ssam switch (errno) { 41514869Ssam 41614869Ssam case ENXIO: 41722485Ssklower fprintf(stderr, "%s: no such interface\n", cmd); 41814869Ssam break; 41914869Ssam 42014869Ssam case EPERM: 42116822Slepreau fprintf(stderr, "%s: permission denied\n", cmd); 42214869Ssam break; 42314869Ssam 42414869Ssam default: 42514869Ssam perror(cmd); 42614869Ssam } 42714869Ssam exit(1); 42814869Ssam } 42914869Ssam 43014869Ssam struct in_addr inet_makeaddr(); 43114869Ssam 43222485Ssklower in_getaddr(s, saddr) 43314869Ssam char *s; 43422485Ssklower struct sockaddr *saddr; 43514869Ssam { 43622485Ssklower register struct sockaddr_in *sin = (struct sockaddr_in *)saddr; 43714869Ssam struct hostent *hp; 43814869Ssam struct netent *np; 43914869Ssam int val; 44014869Ssam 44121811Skarels sin->sin_family = AF_INET; 442*37227Ssklower sin->sin_len = sizeof(*sin); 44321811Skarels val = inet_addr(s); 44421811Skarels if (val != -1) { 44521811Skarels sin->sin_addr.s_addr = val; 44621811Skarels return; 44721811Skarels } 44814869Ssam hp = gethostbyname(s); 44914869Ssam if (hp) { 45014869Ssam sin->sin_family = hp->h_addrtype; 45114869Ssam bcopy(hp->h_addr, (char *)&sin->sin_addr, hp->h_length); 45214869Ssam return; 45314869Ssam } 45414869Ssam np = getnetbyname(s); 45514869Ssam if (np) { 45614869Ssam sin->sin_family = np->n_addrtype; 45714869Ssam sin->sin_addr = inet_makeaddr(np->n_net, INADDR_ANY); 45814869Ssam return; 45914869Ssam } 46014869Ssam fprintf(stderr, "%s: bad value\n", s); 46114869Ssam exit(1); 46214869Ssam } 46314869Ssam 46414869Ssam /* 46514869Ssam * Print a value a la the %b format of the kernel's printf 46614869Ssam */ 46714869Ssam printb(s, v, bits) 46814869Ssam char *s; 46914869Ssam register char *bits; 47014869Ssam register unsigned short v; 47114869Ssam { 47214869Ssam register int i, any = 0; 47314869Ssam register char c; 47414869Ssam 47514869Ssam if (bits && *bits == 8) 47614869Ssam printf("%s=%o", s, v); 47714869Ssam else 47814869Ssam printf("%s=%x", s, v); 47914869Ssam bits++; 48014869Ssam if (bits) { 48114869Ssam putchar('<'); 48214869Ssam while (i = *bits++) { 48314869Ssam if (v & (1 << (i-1))) { 48414869Ssam if (any) 48514869Ssam putchar(','); 48614869Ssam any = 1; 48714869Ssam for (; (c = *bits) > 32; bits++) 48814869Ssam putchar(c); 48914869Ssam } else 49014869Ssam for (; *bits > 32; bits++) 49114869Ssam ; 49214869Ssam } 49314869Ssam putchar('>'); 49414869Ssam } 49514869Ssam } 49622485Ssklower 49722485Ssklower xns_getaddr(addr, saddr) 49822485Ssklower char *addr; 49922485Ssklower struct sockaddr *saddr; 50022485Ssklower { 50126101Ssklower struct sockaddr_ns *sns = (struct sockaddr_ns *)saddr; 50226101Ssklower struct ns_addr ns_addr(); 50322485Ssklower sns->sns_family = AF_NS; 504*37227Ssklower sns->sns_len = sizeof(*sns); 50526101Ssklower sns->sns_addr = ns_addr(addr); 50622485Ssklower } 507