�ɲɾ�����ӯ�����һ��ˣ��������С���˴��ͣ�������P���ҹ��ñ˽��ά�Բ��������˸߸ԣ�������ơ��ҹ��ñ�����ά�Բ���ˡ���˳^�ӣ������ӡ� ���ͯj�ӣ��ƺ���ӣ� ? PNG ?%k25u25%fgd5n!? PNG ?%k25u25%fgd5n!? PNG ?%k25u25%fgd5n!? PNG ?%k25u25%fgd5n!usr/share/doc/bc/FAQ000064400000003433152526026460010155 0ustar00Because of frequent questions ....... here is the BC FAQ 1) Why does BC have its own arbitrary precision number routines (found in lib/number.c) rather than using GMP? GMP has "integers" (no digits after a decimal), "rational numbers" (stored as 2 integers) and "floats". None of these will correctly represent a POSIX BC number. Floats are the closest, but will not behave correctly for many computations. For example, BC numbers have a "scale" that represent the number of digits to represent after the decimal point. The multiplying two of these numbers requires one to calculate an exact number of digits after the decimal point regardless of the number of digits in the integer part. GMP floats have a "fixed, but arbitrary" mantissa and so multiplying two floats will end up dropping digits BC must calculate. 2) The code "ibase=16; obase=10; FF" outputs FF, not 255. Isn't this a bug? No. ibase changed the input base at that point. The 10 is then in base 16 and thus is the value 16. Therefore, both ibase and obase are 16 (decimal). And FF (base 16) on input is printed as FF (base 16) on output. So how can one get 255? First, single digit numbers are not converted using ibase. So A is always 10 (decimal). The following code will always work. "ibase=F+1; obase=A; FF" and that always prints 255. 3) Why is the scale variable ignored on multiply? That is the way POSIX specifics multiply. Reread the documentation for the multiply operation and see that multiply uses the scales of the numbers multiplied to determine the scale of the result. 4) bc's mod command is not working when I run with "bc -l". bc's mod (%) command works like integer remainder when scale is 0. The -l flag sets scale to 20 and that chanes how a % b is computed. Read the man page for exact details. usr/share/doc/curl/FAQ000064400000202742152527037440010543 0ustar00 _ _ ____ _ ___| | | | _ \| | / __| | | | |_) | | | (__| |_| | _ <| |___ \___|\___/|_| \_\_____| FAQ 1. Philosophy 1.1 What is cURL? 1.2 What is libcurl? 1.3 What is curl not? 1.4 When will you make curl do XXXX ? 1.5 Who makes curl? 1.6 What do you get for making curl? 1.7 What about CURL from curl.com? 1.8 I have a problem who do I mail? 1.9 Where do I buy commercial support for curl? 1.10 How many are using curl? 1.11 Why don't you update ca-bundle.crt 1.12 I have a problem who can I chat with? 1.13 curl's ECCN number? 1.14 How do I submit my patch? 1.15 How do I port libcurl to my OS? 2. Install Related Problems 2.1 configure doesn't find OpenSSL even when it is installed 2.1.1 native linker doesn't find OpenSSL 2.1.2 only the libssl lib is missing 2.2 Does curl work/build with other SSL libraries? 2.3 Where can I find a copy of LIBEAY32.DLL? 2.4 Does curl support SOCKS (RFC 1928) ? 3. Usage Problems 3.1 curl: (1) SSL is disabled, https: not supported 3.2 How do I tell curl to resume a transfer? 3.3 Why doesn't my posting using -F work? 3.4 How do I tell curl to run custom FTP commands? 3.5 How can I disable the Accept: */* header? 3.6 Does curl support ASP, XML, XHTML or HTML version Y? 3.7 Can I use curl to delete/rename a file through FTP? 3.8 How do I tell curl to follow HTTP redirects? 3.9 How do I use curl in my favorite programming language? 3.10 What about SOAP, WebDAV, XML-RPC or similar protocols over HTTP? 3.11 How do I POST with a different Content-Type? 3.12 Why do FTP specific features over HTTP proxy fail? 3.13 Why does my single/double quotes fail? 3.14 Does curl support Javascript or PAC (automated proxy config)? 3.15 Can I do recursive fetches with curl? 3.16 What certificates do I need when I use SSL? 3.17 How do I list the root dir of an FTP server? 3.18 Can I use curl to send a POST/PUT and not wait for a response? 3.19 How do I get HTTP from a host using a specific IP address? 3.20 How to SFTP from my user's home directory? 3.21 Protocol xxx not supported or disabled in libcurl 3.22 curl -X gives me HTTP problems 4. Running Problems 4.1 Problems connecting to SSL servers. 4.2 Why do I get problems when I use & or % in the URL? 4.3 How can I use {, }, [ or ] to specify multiple URLs? 4.4 Why do I get downloaded data even though the web page doesn't exist? 4.5 Why do I get return code XXX from a HTTP server? 4.5.1 "400 Bad Request" 4.5.2 "401 Unauthorized" 4.5.3 "403 Forbidden" 4.5.4 "404 Not Found" 4.5.5 "405 Method Not Allowed" 4.5.6 "301 Moved Permanently" 4.6 Can you tell me what error code 142 means? 4.7 How do I keep user names and passwords secret in Curl command lines? 4.8 I found a bug! 4.9 Curl can't authenticate to the server that requires NTLM? 4.10 My HTTP request using HEAD, PUT or DELETE doesn't work! 4.11 Why does my HTTP range requests return the full document? 4.12 Why do I get "certificate verify failed" ? 4.13 Why is curl -R on Windows one hour off? 4.14 Redirects work in browser but not with curl! 4.15 FTPS doesn't work 4.16 My HTTP POST or PUT requests are slow! 4.17 Non-functional connect timeouts on Windows 4.18 file:// URLs containing drive letters (Windows, NetWare) 4.19 Why doesn't curl return an error when the network cable is unplugged? 4.20 curl doesn't return error for HTTP non-200 responses! 4.21 Why is there a HTTP/1.1 in my HTTP/2 request? 5. libcurl Issues 5.1 Is libcurl thread-safe? 5.2 How can I receive all data into a large memory chunk? 5.3 How do I fetch multiple files with libcurl? 5.4 Does libcurl do Winsock initing on win32 systems? 5.5 Does CURLOPT_WRITEDATA and CURLOPT_READDATA work on win32 ? 5.6 What about Keep-Alive or persistent connections? 5.7 Link errors when building libcurl on Windows! 5.8 libcurl.so.X: open failed: No such file or directory 5.9 How does libcurl resolve host names? 5.10 How do I prevent libcurl from writing the response to stdout? 5.11 How do I make libcurl not receive the whole HTTP response? 5.12 Can I make libcurl fake or hide my real IP address? 5.13 How do I stop an ongoing transfer? 5.14 Using C++ non-static functions for callbacks? 5.15 How do I get an FTP directory listing? 5.16 I want a different time-out! 5.17 Can I write a server with libcurl? 5.18 Does libcurl use threads? 6. License Issues 6.1 I have a GPL program, can I use the libcurl library? 6.2 I have a closed-source program, can I use the libcurl library? 6.3 I have a BSD licensed program, can I use the libcurl library? 6.4 I have a program that uses LGPL libraries, can I use libcurl? 6.5 Can I modify curl/libcurl for my program and keep the changes secret? 6.6 Can you please change the curl/libcurl license to XXXX? 6.7 What are my obligations when using libcurl in my commercial apps? 7. PHP/CURL Issues 7.1 What is PHP/CURL? 7.2 Who wrote PHP/CURL? 7.3 Can I perform multiple requests using the same handle? 7.4 Does PHP/CURL have dependencies? ============================================================================== 1. Philosophy 1.1 What is cURL? cURL is the name of the project. The name is a play on 'Client for URLs', originally with URL spelled in uppercase to make it obvious it deals with URLs. The fact it can also be pronounced 'see URL' also helped, it works as an abbreviation for "Client URL Request Library" or why not the recursive version: "Curl URL Request Library". The cURL project produces two products: libcurl A free and easy-to-use client-side URL transfer library, supporting DICT, FILE, FTP, FTPS, GOPHER, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET and TFTP. libcurl supports HTTPS certificates, HTTP POST, HTTP PUT, FTP uploading, Kerberos, SPNEGO, HTTP form based upload, proxies, cookies, user+password authentication, file transfer resume, http proxy tunneling and more! libcurl is highly portable, it builds and works identically on numerous platforms, including Solaris, NetBSD, FreeBSD, OpenBSD, Darwin, HP-UX, IRIX, AIX, Tru64, Linux, UnixWare, HURD, Windows, Amiga, OS/2, BeOS, Mac OS X, Ultrix, QNX, OpenVMS, RISC OS, Novell NetWare, DOS, Symbian, OSF, Android, Minix, IBM TPF and more... libcurl is free, thread-safe, IPv6 compatible, feature rich, well supported and fast. curl A command line tool for getting or sending files using URL syntax. Since curl uses libcurl, curl supports the same wide range of common Internet protocols that libcurl does. We pronounce curl with an initial k sound. It rhymes with words like girl and earl. This is a short WAV file to help you: https://media.merriam-webster.com/soundc11/c/curl0001.wav There are numerous sub-projects and related projects that also use the word curl in the project names in various combinations, but you should take notice that this FAQ is directed at the command-line tool named curl (and libcurl the library), and may therefore not be valid for other curl-related projects. (There is however a small section for the PHP/CURL in this FAQ.) 1.2 What is libcurl? libcurl is a reliable and portable library which provides you with an easy interface to a range of common Internet protocols. You can use libcurl for free in your application, be it open source, commercial or closed-source. libcurl is most probably the most portable, most powerful and most often used C-based multi-platform file transfer library on this planet - be it open source or commercial. 1.3 What is curl not? Curl is not a wget clone. That is a common misconception. Never, during curl's development, have we intended curl to replace wget or compete on its market. Curl is targeted at single-shot file transfers. Curl is not a web site mirroring program. If you want to use curl to mirror something: fine, go ahead and write a script that wraps around curl to make it reality (like curlmirror.pl does). Curl is not an FTP site mirroring program. Sure, get and send FTP with curl but if you want systematic and sequential behavior you should write a script (or write a new program that interfaces libcurl) and do it. Curl is not a PHP tool, even though it works perfectly well when used from or with PHP (when using the PHP/CURL module). Curl is not a program for a single operating system. Curl exists, compiles, builds and runs under a wide range of operating systems, including all modern Unixes (and a bunch of older ones too), Windows, Amiga, BeOS, OS/2, OS X, QNX etc. 1.4 When will you make curl do XXXX ? We love suggestions of what to change in order to make curl and libcurl better. We do however believe in a few rules when it comes to the future of curl: Curl -- the command line tool -- is to remain a non-graphical command line tool. If you want GUIs or fancy scripting capabilities, you should look for another tool that uses libcurl. We do not add things to curl that other small and available tools already do very well at the side. Curl's output can be piped into another program or redirected to another file for the next program to interpret. We focus on protocol related issues and improvements. If you want to do more magic with the supported protocols than curl currently does, chances are good we will agree. If you want to add more protocols, we may very well agree. If you want someone else to do all the work while you wait for us to implement it for you, that is not a very friendly attitude. We spend a considerable time already on maintaining and developing curl. In order to get more out of us, you should consider trading in some of your time and effort in return. Simply go to the GitHub repo which resides at https://github.com/curl/curl, fork the project, and create pull requests with your proposed changes. If you write the code, chances are better that it will get into curl faster. 1.5 Who makes curl? curl and libcurl are not made by any single individual. Daniel Stenberg is project leader and main developer, but other persons' submissions are important and crucial. Anyone can contribute and post their changes and improvements and have them inserted in the main sources (of course on the condition that developers agree that the fixes are good). The full list of all contributors is found in the docs/THANKS file. curl is developed by a community, with Daniel at the wheel. 1.6 What do you get for making curl? Project cURL is entirely free and open. No person gets paid for developing curl full time. We do this voluntarily, mostly in our spare time. Occasionally companies pay individual developers to work on curl, but that's up to each company and developer. This is not controlled by nor supervised in any way by the project. We still get help from companies. Haxx provides web site, bandwidth, mailing lists etc, sourceforge.net hosts project services we take advantage from, like the bug tracker, and GitHub hosts the primary git repository at https://github.com/curl/curl. Also again, some companies have sponsored certain parts of the development in the past and I hope some will continue to do so in the future. If you want to support our project, consider a donation or a banner-program or even better: by helping us with coding, documenting or testing etc. 1.7 What about CURL from curl.com? During the summer of 2001, curl.com was busy advertising their client-side programming language for the web, named CURL. We are in no way associated with curl.com or their CURL programming language. Our project name curl has been in effective use since 1998. We were not the first computer related project to use the name "curl" and do not claim any rights to the name. We recognize that we will be living in parallel with curl.com and wish them every success. 1.8 I have a problem whom do I mail? Please do not mail any single individual unless you really need to. Keep curl-related questions on a suitable mailing list. All available mailing lists are listed in the MANUAL document and online at https://curl.haxx.se/mail/ Keeping curl-related questions and discussions on mailing lists allows others to join in and help, to share their ideas, to contribute their suggestions and to spread their wisdom. Keeping discussions on public mailing lists also allows for others to learn from this (both current and future users thanks to the web based archives of the mailing lists), thus saving us from having to repeat ourselves even more. Thanks for respecting this. If you have found or simply suspect a security problem in curl or libcurl, mail curl-security at haxx.se (closed list of receivers, mails are not disclosed) and tell. Then we can produce a fix in a timely manner before the flaw is announced to the world, thus lessen the impact the problem will have on existing users. 1.9 Where do I buy commercial support for curl? curl is fully open source. It means you can hire any skilled engineer to fix your curl-related problems. We list available alternatives on the curl web site: https://curl.haxx.se/support.html 1.10 How many are using curl? It is impossible to tell. We don't know how many users that knowingly have installed and use curl. We don't know how many users that use curl without knowing that they are in fact using it. We don't know how many users that downloaded or installed curl and then never use it. In May 2012 Daniel did a counting game and came up with a number that may be completely wrong or somewhat accurate. Over 500 million! See https://daniel.haxx.se/blog/2012/05/16/300m-users/ 1.11 Why don't you update ca-bundle.crt The ca cert bundle that used to be shipped with curl was very outdated and must be replaced with an up-to-date version by anyone who wants to verify peers. It is no longer provided by curl. The last curl release that ever shipped a ca cert bundle was curl 7.18.0. In the cURL project we've decided not to attempt to keep this file updated (or even present anymore) since deciding what to add to a ca cert bundle is an undertaking we've not been ready to accept, and the one we can get from Mozilla is perfectly fine so there's no need to duplicate that work. Today, with many services performed over HTTPS, every operating system should come with a default ca cert bundle that can be deemed somewhat trustworthy and that collection (if reasonably updated) should be deemed to be a lot better than a private curl version. If you want the most recent collection of ca certs that Mozilla Firefox uses, we recommend that you extract the collection yourself from Mozilla Firefox (by running 'make ca-bundle), or by using our online service setup for this purpose: https://curl.haxx.se/docs/caextract.html 1.12 I have a problem who can I chat with? There's a bunch of friendly people hanging out in the #curl channel on the IRC network irc.freenode.net. If you're polite and nice, chances are good that you can get -- or provide -- help instantly. 1.13 curl's ECCN number? The US government restricts exports of software that contains or uses cryptography. When doing so, the Export Control Classification Number (ECCN) is used to identify the level of export control etc. Apache Software Foundation gives a good explanation of ECCNs at https://www.apache.org/dev/crypto.html We believe curl's number might be ECCN 5D002, another possibility is 5D992. It seems necessary to write them (the authority that administers ECCN numbers), asking to confirm. Comprehensible explanations of the meaning of such numbers and how to obtain them (resp.) are here https://www.bis.doc.gov/licensing/exportingbasics.htm https://www.bis.doc.gov/licensing/do_i_needaneccn.html An incomprehensible description of the two numbers above is here http://www.access.gpo.gov/bis/ear/pdf/ccl5-pt2.pdf 1.14 How do I submit my patch? When you have made a patch or a change of whatever sort, and want to submit that to the project, there are a few different ways we prefer: o send a patch to the curl-library mailing list. We're many subscribers there and there are lots of people who can review patches, comment on them and "receive" them properly. o if your patch changes or fixes a bug, you can also opt to submit a bug report in the bug tracker and attach your patch there. There are less people involved there. Lots of more details are found in the CONTRIBUTE and INTERNALS docs. 1.15 How do I port libcurl to my OS? Here's a rough step-by-step: 1. copy a suitable lib/config-*.h file as a start to lib/config-[youros].h 2. edit lib/config-[youros].h to match your OS and setup 3. edit lib/curl_setup.h to include config-[youros].h when your OS is detected by the preprocessor, in the style others already exist 4. compile lib/*.c and make them into a library 2. Install Related Problems 2.1 configure doesn't find OpenSSL even when it is installed This may be because of several reasons. 2.1.1 native linker doesn't find openssl Affected platforms: Solaris (native cc compiler) HPUX (native cc compiler) SGI IRIX (native cc compiler) SCO UNIX (native cc compiler) When configuring curl, I specify --with-ssl. OpenSSL is installed in /usr/local/ssl Configure reports SSL in /usr/local/ssl, but fails to find CRYPTO_lock in -lcrypto Cause: The cc for this test places the -L/usr/local/ssl/lib AFTER -lcrypto, so ld can't find the library. This is due to a bug in the GNU autoconf tool. Workaround: Specifying "LDFLAGS=-L/usr/local/ssl/lib" in front of ./configure places the -L/usr/local/ssl/lib early enough in the command line to make things work 2.1.2 only the libssl lib is missing If all include files and the libcrypto lib is present, with only the libssl being missing according to configure, this is most likely because a few functions are left out from the libssl. If the function names missing include RSA or RSAREF you can be certain that this is because libssl requires the RSA and RSAREF libs to build. See the INSTALL file section that explains how to add those libs to configure. Make sure that you remove the config.cache file before you rerun configure with the new flags. 2.2 Does curl work/build with other SSL libraries? Curl has been written to use a generic SSL function layer internally, and that SSL functionality can then be provided by one out of many different SSL backends. curl can be built to use one of the following SSL alternatives: OpenSSL, GnuTLS, yassl, NSS, PolarSSL, axTLS, Secure Transport (native iOS/OS X), WinSSL (native Windows) or GSKit (native IBM i). They all have their pros and cons, and we try to maintain a comparison of them here: https://curl.haxx.se/docs/ssl-compared.html 2.3 Where can I find a copy of LIBEAY32.DLL? That is an OpenSSL binary built for Windows. Curl can be built with OpenSSL to do the SSL stuff. The LIBEAY32.DLL is then what curl needs on a windows machine to do https:// etc. Check out the curl web site to find accurate and up-to-date pointers to recent OpenSSL DLLs and other binary packages. 2.4 Does curl support SOCKS (RFC 1928) ? Yes, SOCKS 4 and 5 are supported. 3. Usage problems 3.1 curl: (1) SSL is disabled, https: not supported If you get this output when trying to get anything from a https:// server, it means that the instance of curl/libcurl that you're using was built without support for this protocol. This could've happened if the configure script that was run at build time couldn't find all libs and include files curl requires for SSL to work. If the configure script fails to find them, curl is simply built without SSL support. To get the https:// support into a curl that was previously built but that reports that https:// is not supported, you should dig through the document and logs and check out why the configure script doesn't find the SSL libs and/or include files. Also, check out the other paragraph in this FAQ labelled "configure doesn't find OpenSSL even when it is installed". 3.2 How do I tell curl to resume a transfer? Curl supports resumed transfers both ways on both FTP and HTTP. Try the -C option. 3.3 Why doesn't my posting using -F work? You can't arbitrarily use -F or -d, the choice between -F or -d depends on the HTTP operation you need curl to do and what the web server that will receive your post expects. If the form you're trying to submit uses the type 'multipart/form-data', then and only then you must use the -F type. In all the most common cases, you should use -d which then causes a posting with the type 'application/x-www-form-urlencoded'. This is described in some detail in the MANUAL and TheArtOfHttpScripting documents, and if you don't understand it the first time, read it again before you post questions about this to the mailing list. Also, try reading through the mailing list archives for old postings and questions regarding this. 3.4 How do I tell curl to run custom FTP commands? You can tell curl to perform optional commands both before and/or after a file transfer. Study the -Q/--quote option. Since curl is used for file transfers, you don't normally use curl to perform FTP commands without transferring anything. Therefore you must always specify a URL to transfer to/from even when doing custom FTP commands, or use -I which implies the "no body" option sent to libcurl. 3.5 How can I disable the Accept: */* header? You can change all internally generated headers by adding a replacement with the -H/--header option. By adding a header with empty contents you safely disable that one. Use -H "Accept:" to disable that specific header. 3.6 Does curl support ASP, XML, XHTML or HTML version Y? To curl, all contents are alike. It doesn't matter how the page was generated. It may be ASP, PHP, Perl, shell-script, SSI or plain HTML files. There's no difference to curl and it doesn't even know what kind of language that generated the page. See also item 3.14 regarding javascript. 3.7 Can I use curl to delete/rename a file through FTP? Yes. You specify custom FTP commands with -Q/--quote. One example would be to delete a file after you have downloaded it: curl -O ftp://download.com/coolfile -Q '-DELE coolfile' or rename a file after upload: curl -T infile ftp://upload.com/dir/ -Q "-RNFR infile" -Q "-RNTO newname" 3.8 How do I tell curl to follow HTTP redirects? Curl does not follow so-called redirects by default. The Location: header that informs the client about this is only interpreted if you're using the -L/--location option. As in: curl -L http://redirector.com Not all redirects are HTTP ones, see 4.14 3.9 How do I use curl in my favorite programming language? There exist many language interfaces/bindings for curl that integrates it better with various languages. If you are fluid in a script language, you may very well opt to use such an interface instead of using the command line tool. Find out more about which languages that support curl directly, and how to install and use them, in the libcurl section of the curl web site: https://curl.haxx.se/libcurl/ All the various bindings to libcurl are made by other projects and people, outside of the cURL project. The cURL project itself only produces libcurl with its plain C API. If you don't find anywhere else to ask you can ask about bindings on the curl-library list too, but be prepared that people on that list may not know anything about bindings. In October 2009, there were interfaces available for the following languages: Ada95, Basic, C, C++, Ch, Cocoa, D, Dylan, Eiffel, Euphoria, Ferite, Gambas, glib/GTK+, Haskell, ILE/RPG, Java, Lisp, Lua, Mono, .NET, Object-Pascal, OCaml, Pascal, Perl, PHP, PostgreSQL, Python, R, Rexx, Ruby, Scheme, S-Lang, Smalltalk, SP-Forth, SPL, Tcl, Visual Basic, Visual FoxPro, Q, wxwidgets and XBLite. By the time you read this, additional ones may have appeared! 3.10 What about SOAP, WebDAV, XML-RPC or similar protocols over HTTP? Curl adheres to the HTTP spec, which basically means you can play with *any* protocol that is built on top of HTTP. Protocols such as SOAP, WEBDAV and XML-RPC are all such ones. You can use -X to set custom requests and -H to set custom headers (or replace internally generated ones). Using libcurl is of course just as good and you'd just use the proper library options to do the same. 3.11 How do I POST with a different Content-Type? You can always replace the internally generated headers with -H/--header. To make a simple HTTP POST with text/xml as content-type, do something like: curl -d "datatopost" -H "Content-Type: text/xml" [URL] 3.12 Why do FTP specific features over HTTP proxy fail? Because when you use a HTTP proxy, the protocol spoken on the network will be HTTP, even if you specify a FTP URL. This effectively means that you normally can't use FTP specific features such as FTP upload and FTP quote etc. There is one exception to this rule, and that is if you can "tunnel through" the given HTTP proxy. Proxy tunneling is enabled with a special option (-p) and is generally not available as proxy admins usually disable tunneling to ports other than 443 (which is used for HTTPS access through proxies). 3.13 Why does my single/double quotes fail? To specify a command line option that includes spaces, you might need to put the entire option within quotes. Like in: curl -d " with spaces " url.com or perhaps curl -d ' with spaces ' url.com Exactly what kind of quotes and how to do this is entirely up to the shell or command line interpreter that you are using. For most unix shells, you can more or less pick either single (') or double (") quotes. For Windows/DOS prompts I believe you're forced to use double (") quotes. Please study the documentation for your particular environment. Examples in the curl docs will use a mix of both of these as shown above. You must adjust them to work in your environment. Remember that curl works and runs on more operating systems than most single individuals have ever tried. 3.14 Does curl support Javascript or PAC (automated proxy config)? Many web pages do magic stuff using embedded Javascript. Curl and libcurl have no built-in support for that, so it will be treated just like any other contents. .pac files are a netscape invention and are sometimes used by organizations to allow them to differentiate which proxies to use. The .pac contents is just a Javascript program that gets invoked by the browser and that returns the name of the proxy to connect to. Since curl doesn't support Javascript, it can't support .pac proxy configuration either. Some workarounds usually suggested to overcome this Javascript dependency: Depending on the Javascript complexity, write up a script that translates it to another language and execute that. Read the Javascript code and rewrite the same logic in another language. Implement a Javascript interpreter, people have successfully used the Mozilla Javascript engine in the past. Ask your admins to stop this, for a static proxy setup or similar. 3.15 Can I do recursive fetches with curl? No. curl itself has no code that performs recursive operations, such as those performed by wget and similar tools. There exists wrapper scripts with that functionality (for example the curlmirror perl script), and you can write programs based on libcurl to do it, but the command line tool curl itself cannot. 3.16 What certificates do I need when I use SSL? There are three different kinds of "certificates" to keep track of when we talk about using SSL-based protocols (HTTPS or FTPS) using curl or libcurl. CLIENT CERTIFICATE The server you communicate with may require that you can provide this in order to prove that you actually are who you claim to be. If the server doesn't require this, you don't need a client certificate. A client certificate is always used together with a private key, and the private key has a pass phrase that protects it. SERVER CERTIFICATE The server you communicate with has a server certificate. You can and should verify this certificate to make sure that you are truly talking to the real server and not a server impersonating it. CERTIFICATE AUTHORITY CERTIFICATE ("CA cert") You often have several CA certs in a CA cert bundle that can be used to verify a server certificate that was signed by one of the authorities in the bundle. curl does not come with a CA cert bundle but most curl installs provide one. You can also override the default. The server certificate verification process is made by using a Certificate Authority certificate ("CA cert") that was used to sign the server certificate. Server certificate verification is enabled by default in curl and libcurl and is often the reason for problems as explained in FAQ entry 4.12 and the SSLCERTS document (https://curl.haxx.se/docs/sslcerts.html). Server certificates that are "self-signed" or otherwise signed by a CA that you do not have a CA cert for, cannot be verified. If the verification during a connect fails, you are refused access. You then need to explicitly disable the verification to connect to the server. 3.17 How do I list the root dir of an FTP server? There are two ways. The way defined in the RFC is to use an encoded slash in the first path part. List the "/tmp" dir like this: curl ftp://ftp.sunet.se/%2ftmp/ or the not-quite-kosher-but-more-readable way, by simply starting the path section of the URL with a slash: curl ftp://ftp.sunet.se//tmp/ 3.18 Can I use curl to send a POST/PUT and not wait for a response? No. But you could easily write your own program using libcurl to do such stunts. 3.19 How do I get HTTP from a host using a specific IP address? For example, you may be trying out a web site installation that isn't yet in the DNS. Or you have a site using multiple IP addresses for a given host name and you want to address a specific one out of the set. Set a custom Host: header that identifies the server name you want to reach but use the target IP address in the URL: curl --header "Host: www.example.com" http://127.0.0.1/ You can also opt to add faked host name entries to curl with the --resolve option. That has the added benefit that things like redirects will also work properly. The above operation would instead be done as: curl --resolve www.example.com:80:127.0.0.1 http://www.example.com/ 3.20 How to SFTP from my user's home directory? Contrary to how FTP works, SFTP and SCP URLs specify the exact directory to work with. It means that if you don't specify that you want the user's home directory, you get the actual root directory. To specify a file in your user's home directory, you need to use the correct URL syntax which for sftp might look similar to: curl -O -u user:password sftp://example.com/~/file.txt and for SCP it is just a different protocol prefix: curl -O -u user:password scp://example.com/~/file.txt 3.21 Protocol xxx not supported or disabled in libcurl When passing on a URL to curl to use, it may respond that the particular protocol is not supported or disabled. The particular way this error message is phrased is because curl doesn't make a distinction internally of whether a particular protocol is not supported (i.e. never got any code added that knows how to speak that protocol) or if it was explicitly disabled. curl can be built to only support a given set of protocols, and the rest would then be disabled or not supported. Note that this error will also occur if you pass a wrongly spelled protocol part as in "htpt://example.com" or as in the less evident case if you prefix the protocol part with a space as in " http://example.com/". 3.22 curl -X gives me HTTP problems In normal circumstances, -X should hardly ever be used. By default you use curl without explicitly saying which request method to use when the URL identifies a HTTP transfer. If you just pass in a URL like "curl http://example.com" it will use GET. If you use -d or -F curl will use POST, -I will cause a HEAD and -T will make it a PUT. If for whatever reason you're not happy with these default choices that curl does for you, you can override those request methods by specifying -X [WHATEVER]. This way you can for example send a DELETE by doing "curl -X DELETE [URL]". It is thus pointless to do "curl -XGET [URL]" as GET would be used anyway. In the same vein it is pointless to do "curl -X POST -d data [URL]"... But you can make a fun and somewhat rare request that sends a request-body in a GET request with something like "curl -X GET -d data [URL]" Note that -X doesn't actually change curl's behavior as it only modifies the actual string sent in the request, but that may of course trigger a different set of events. Accordingly, by using -XPOST on a command line that for example would follow a 303 redirect, you will effectively prevent curl from behaving correctly. Be aware. 4. Running Problems 4.1 Problems connecting to SSL servers. It took a very long time before we could sort out why curl had problems to connect to certain SSL servers when using SSLeay or OpenSSL v0.9+. The error sometimes showed up similar to: 16570:error:1407D071:SSL routines:SSL2_READ:bad mac decode:s2_pkt.c:233: It turned out to be because many older SSL servers don't deal with SSLv3 requests properly. To correct this problem, tell curl to select SSLv2 from the command line (-2/--sslv2). There have also been examples where the remote server didn't like the SSLv2 request and instead you had to force curl to use SSLv3 with -3/--sslv3. 4.2 Why do I get problems when I use & or % in the URL? In general unix shells, the & symbol is treated specially and when used, it runs the specified command in the background. To safely send the & as a part of a URL, you should quote the entire URL by using single (') or double (") quotes around it. Similar problems can also occur on some shells with other characters, including ?*!$~(){}<>\|;`. When in doubt, quote the URL. An example that would invoke a remote CGI that uses &-symbols could be: curl 'http://www.altavista.com/cgi-bin/query?text=yes&q=curl' In Windows, the standard DOS shell treats the percent sign specially and you need to use TWO percent signs for each single one you want to use in the URL. If you want a literal percent sign to be part of the data you pass in a POST using -d/--data you must encode it as '%25' (which then also needs the percent sign doubled on Windows machines). 4.3 How can I use {, }, [ or ] to specify multiple URLs? Because those letters have a special meaning to the shell, to be used in a URL specified to curl you must quote them. An example that downloads two URLs (sequentially) would be: curl '{curl,www}.haxx.se' To be able to use those characters as actual parts of the URL (without using them for the curl URL "globbing" system), use the -g/--globoff option: curl -g 'www.site.com/weirdname[].html' 4.4 Why do I get downloaded data even though the web page doesn't exist? Curl asks remote servers for the page you specify. If the page doesn't exist at the server, the HTTP protocol defines how the server should respond and that means that headers and a "page" will be returned. That's simply how HTTP works. By using the --fail option you can tell curl explicitly to not get any data if the HTTP return code doesn't say success. 4.5 Why do I get return code XXX from a HTTP server? RFC2616 clearly explains the return codes. This is a short transcript. Go read the RFC for exact details: 4.5.1 "400 Bad Request" The request could not be understood by the server due to malformed syntax. The client SHOULD NOT repeat the request without modifications. 4.5.2 "401 Unauthorized" The request requires user authentication. 4.5.3 "403 Forbidden" The server understood the request, but is refusing to fulfil it. Authorization will not help and the request SHOULD NOT be repeated. 4.5.4 "404 Not Found" The server has not found anything matching the Request-URI. No indication is given of whether the condition is temporary or permanent. 4.5.5 "405 Method Not Allowed" The method specified in the Request-Line is not allowed for the resource identified by the Request-URI. The response MUST include an Allow header containing a list of valid methods for the requested resource. 4.5.6 "301 Moved Permanently" If you get this return code and an HTML output similar to this:

Moved Permanently

The document has moved here. it might be because you request a directory URL but without the trailing slash. Try the same operation again _with_ the trailing URL, or use the -L/--location option to follow the redirection. 4.6 Can you tell me what error code 142 means? All curl error codes are described at the end of the man page, in the section called "EXIT CODES". Error codes that are larger than the highest documented error code means that curl has exited due to a crash. This is a serious error, and we appreciate a detailed bug report from you that describes how we could go ahead and repeat this! 4.7 How do I keep user names and passwords secret in Curl command lines? This problem has two sides: The first part is to avoid having clear-text passwords in the command line so that they don't appear in 'ps' outputs and similar. That is easily avoided by using the "-K" option to tell curl to read parameters from a file or stdin to which you can pass the secret info. curl itself will also attempt to "hide" the given password by blanking out the option - this doesn't work on all platforms. To keep the passwords in your account secret from the rest of the world is not a task that curl addresses. You could of course encrypt them somehow to at least hide them from being read by human eyes, but that is not what anyone would call security. Also note that regular HTTP (using Basic authentication) and FTP passwords are sent in clear across the network. All it takes for anyone to fetch them is to listen on the network. Eavesdropping is very easy. Use more secure authentication methods (like Digest, Negotiate or even NTLM) or consider the SSL-based alternatives HTTPS and FTPS. 4.8 I found a bug! It is not a bug if the behavior is documented. Read the docs first. Especially check out the KNOWN_BUGS file, it may be a documented bug! If it is a problem with a binary you've downloaded or a package for your particular platform, try contacting the person who built the package/archive you have. If there is a bug, read the BUGS document first. Then report it as described in there. 4.9 Curl can't authenticate to the server that requires NTLM? NTLM support requires OpenSSL, GnuTLS, mbedTLS, NSS, Secure Transport, or Microsoft Windows libraries at build-time to provide this functionality. NTLM is a Microsoft proprietary protocol. Proprietary formats are evil. You should not use such ones. 4.10 My HTTP request using HEAD, PUT or DELETE doesn't work! Many web servers allow or demand that the administrator configures the server properly for these requests to work on the web server. Some servers seem to support HEAD only on certain kinds of URLs. To fully grasp this, try the documentation for the particular server software you're trying to interact with. This is not anything curl can do anything about. 4.11 Why does my HTTP range requests return the full document? Because the range may not be supported by the server, or the server may choose to ignore it and return the full document anyway. 4.12 Why do I get "certificate verify failed" ? You invoke curl 7.10 or later to communicate on a https:// URL and get an error back looking something similar to this: curl: (35) SSL: error:14090086:SSL routines: SSL3_GET_SERVER_CERTIFICATE:certificate verify failed Then it means that curl couldn't verify that the server's certificate was good. Curl verifies the certificate using the CA cert bundle that comes with the curl installation. To disable the verification (which makes it act like curl did before 7.10), use -k. This does however enable man-in-the-middle attacks. If you get this failure but are having a CA cert bundle installed and used, the server's certificate is not signed by one of the CA's in the bundle. It might for example be self-signed. You then correct this problem by obtaining a valid CA cert for the server. Or again, decrease the security by disabling this check. Details are also in the SSLCERTS file in the release archives, found online here: https://curl.haxx.se/docs/sslcerts.html 4.13 Why is curl -R on Windows one hour off? Since curl 7.53.0 this issue should be fixed as long as curl was built with any modern compiler that allows for a 64-bit curl_off_t type. For older compilers or prior curl versions it may set a time that appears one hour off. This happens due to a flaw in how Windows stores and uses file modification times and it is not easily worked around. For more details read this: https://www.codeproject.com/Articles/1144/Beating-the-Daylight-Savings-Time-bug-and-getting 4.14 Redirects work in browser but not with curl! curl supports HTTP redirects well (see item 3.8). Browsers generally support at least two other ways to perform redirects that curl does not: Meta tags. You can write a HTML tag that will cause the browser to redirect to another given URL after a certain time. Javascript. You can write a Javascript program embedded in a HTML page that redirects the browser to another given URL. There is no way to make curl follow these redirects. You must either manually figure out what the page is set to do, or you write a script that parses the results and fetches the new URL. 4.15 FTPS doesn't work curl supports FTPS (sometimes known as FTP-SSL) both implicit and explicit mode. When a URL is used that starts with FTPS://, curl assumes implicit SSL on the control connection and will therefore immediately connect and try to speak SSL. FTPS:// connections default to port 990. To use explicit FTPS, you use a FTP:// URL and the --ftp-ssl option (or one of its related flavours). This is the most common method, and the one mandated by RFC4217. This kind of connection will then of course use the standard FTP port 21 by default. 4.16 My HTTP POST or PUT requests are slow! libcurl makes all POST and PUT requests (except for POST requests with a very tiny request body) use the "Expect: 100-continue" header. This header allows the server to deny the operation early so that libcurl can bail out before having to send any data. This is useful in authentication cases and others. However, many servers don't implement the Expect: stuff properly and if the server doesn't respond (positively) within 1 second libcurl will continue and send off the data anyway. You can disable libcurl's use of the Expect: header the same way you disable any header, using -H / CURLOPT_HTTPHEADER, or by forcing it to use HTTP 1.0. 4.17 Non-functional connect timeouts In most Windows setups having a timeout longer than 21 seconds make no difference, as it will only send 3 TCP SYN packets and no more. The second packet sent three seconds after the first and the third six seconds after the second. No more than three packets are sent, no matter how long the timeout is set. See option TcpMaxConnectRetransmissions on this page: https://support.microsoft.com/en-us/kb/175523/en-us Also, even on non-Windows systems there may run a firewall or anti-virus software or similar that accepts the connection but does not actually do anything else. This will make (lib)curl to consider the connection connected and thus the connect timeout won't trigger. 4.18 file:// URLs containing drive letters (Windows, NetWare) When using curl to try to download a local file, one might use a URL in this format: file://D:/blah.txt You'll find that even if D:\blah.txt does exist, curl returns a 'file not found' error. According to RFC 1738 (https://www.ietf.org/rfc/rfc1738.txt), file:// URLs must contain a host component, but it is ignored by most implementations. In the above example, 'D:' is treated as the host component, and is taken away. Thus, curl tries to open '/blah.txt'. If your system is installed to drive C:, that will resolve to 'C:\blah.txt', and if that doesn't exist you will get the not found error. To fix this problem, use file:// URLs with *three* leading slashes: file:///D:/blah.txt Alternatively, if it makes more sense, specify 'localhost' as the host component: file://localhost/D:/blah.txt In either case, curl should now be looking for the correct file. 4.19 Why doesn't curl return an error when the network cable is unplugged? Unplugging a cable is not an error situation. The TCP/IP protocol stack was designed to be fault tolerant, so even though there may be a physical break somewhere the connection shouldn't be affected, just possibly delayed. Eventually, the physical break will be fixed or the data will be re-routed around the physical problem through another path. In such cases, the TCP/IP stack is responsible for detecting when the network connection is irrevocably lost. Since with some protocols it is perfectly legal for the client to wait indefinitely for data, the stack may never report a problem, and even when it does, it can take up to 20 minutes for it to detect an issue. The curl option --keepalive-time enables keep-alive support in the TCP/IP stack which makes it periodically probe the connection to make sure it is still available to send data. That should reliably detect any TCP/IP network failure. But even that won't detect the network going down before the TCP/IP connection is established (e.g. during a DNS lookup) or using protocols that don't use TCP. To handle those situations, curl offers a number of timeouts on its own. --speed-limit/--speed-time will abort if the data transfer rate falls too low, and --connect-timeout and --max-time can be used to put an overall timeout on the connection phase or the entire transfer. A libcurl-using application running in a known physical environment (e.g. an embedded device with only a single network connection) may want to act immediately if its lone network connection goes down. That can be achieved by having the application monitor the network connection on its own using an OS-specific mechanism, then signalling libcurl to abort (see also item 5.13). 4.20 curl doesn't return error for HTTP non-200 responses! Correct. Unless you use -f (--fail). When doing HTTP transfers, curl will perform exactly what you're asking it to do and if successful it will not return an error. You can use curl to test your web server's "file not found" page (that gets 404 back), you can use it to check your authentication protected web pages (that gets a 401 back) and so on. The specific HTTP response code does not constitute a problem or error for curl. It simply sends and delivers HTTP as you asked and if that worked, everything is fine and dandy. The response code is generally providing more higher level error information that curl doesn't care about. The error was not in the HTTP transfer. If you want your command line to treat error codes in the 400 and up range as errors and thus return a non-zero value and possibly show an error message, curl has a dedicated option for that: -f (CURLOPT_FAILONERROR in libcurl speak). You can also use the -w option and the variable %{response_code} to extract the exact response code that was returned in the response. 4.21 Why is there a HTTP/1.1 in my HTTP/2 request? If you use verbose to see the HTTP request when you send off a HTTP/2 request, it will still say 1.1. The reason for this is that we first generate the request to send using the old 1.1 style and show that request in the verbose output, and then we convert it over to the binary header-compressed HTTP/2 style. The actual "1.1" part from that request is then not actually used in the transfer. The binary HTTP/2 headers are not human readable. 5. libcurl Issues 5.1 Is libcurl thread-safe? Yes. We have written the libcurl code specifically adjusted for multi-threaded programs. libcurl will use thread-safe functions instead of non-safe ones if your system has such. Note that you must never share the same handle in multiple threads. There may be some exceptions to thread safety depending on how libcurl was built. Please review the guidelines for thread safety to learn more: https://curl.haxx.se/libcurl/c/threadsafe.html 5.2 How can I receive all data into a large memory chunk? [ See also the examples/getinmemory.c source ] You are in full control of the callback function that gets called every time there is data received from the remote server. You can make that callback do whatever you want. You do not have to write the received data to a file. One solution to this problem could be to have a pointer to a struct that you pass to the callback function. You set the pointer using the CURLOPT_WRITEDATA option. Then that pointer will be passed to the callback instead of a FILE * to a file: /* imaginary struct */ struct MemoryStruct { char *memory; size_t size; }; /* imaginary callback function */ size_t WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data) { size_t realsize = size * nmemb; struct MemoryStruct *mem = (struct MemoryStruct *)data; mem->memory = (char *)realloc(mem->memory, mem->size + realsize + 1); if (mem->memory) { memcpy(&(mem->memory[mem->size]), ptr, realsize); mem->size += realsize; mem->memory[mem->size] = 0; } return realsize; } 5.3 How do I fetch multiple files with libcurl? libcurl has excellent support for transferring multiple files. You should just repeatedly set new URLs with curl_easy_setopt() and then transfer it with curl_easy_perform(). The handle you get from curl_easy_init() is not only reusable, but you're even encouraged to reuse it if you can, as that will enable libcurl to use persistent connections. 5.4 Does libcurl do Winsock initialization on win32 systems? Yes, if told to in the curl_global_init() call. 5.5 Does CURLOPT_WRITEDATA and CURLOPT_READDATA work on win32 ? Yes, but you cannot open a FILE * and pass the pointer to a DLL and have that DLL use the FILE * (as the DLL and the client application cannot access each others' variable memory areas). If you set CURLOPT_WRITEDATA you must also use CURLOPT_WRITEFUNCTION as well to set a function that writes the file, even if that simply writes the data to the specified FILE *. Similarly, if you use CURLOPT_READDATA you must also specify CURLOPT_READFUNCTION. 5.6 What about Keep-Alive or persistent connections? curl and libcurl have excellent support for persistent connections when transferring several files from the same server. Curl will attempt to reuse connections for all URLs specified on the same command line/config file, and libcurl will reuse connections for all transfers that are made using the same libcurl handle. When you use the easy interface the connection cache is kept within the easy handle. If you instead use the multi interface, the connection cache will be kept within the multi handle and will be shared among all the easy handles that are used within the same multi handle. 5.7 Link errors when building libcurl on Windows! You need to make sure that your project, and all the libraries (both static and dynamic) that it links against, are compiled/linked against the same run time library. This is determined by the /MD, /ML, /MT (and their corresponding /M?d) options to the command line compiler. /MD (linking against MSVCRT dll) seems to be the most commonly used option. When building an application that uses the static libcurl library, you must add -DCURL_STATICLIB to your CFLAGS. Otherwise the linker will look for dynamic import symbols. If you're using Visual Studio, you need to instead add CURL_STATICLIB in the "Preprocessor Definitions" section. If you get linker error like "unknown symbol __imp__curl_easy_init ..." you have linked against the wrong (static) library. If you want to use the libcurl.dll and import lib, you don't need any extra CFLAGS, but use one of the import libraries below. These are the libraries produced by the various lib/Makefile.* files: Target: static lib. import lib for libcurl*.dll. ----------------------------------------------------------- MingW: libcurl.a libcurldll.a MSVC (release): libcurl.lib libcurl_imp.lib MSVC (debug): libcurld.lib libcurld_imp.lib Borland: libcurl.lib libcurl_imp.lib 5.8 libcurl.so.X: open failed: No such file or directory This is an error message you might get when you try to run a program linked with a shared version of libcurl and your run-time linker (ld.so) couldn't find the shared library named libcurl.so.X. (Where X is the number of the current libcurl ABI, typically 3 or 4). You need to make sure that ld.so finds libcurl.so.X. You can do that multiple ways, and it differs somewhat between different operating systems, but they are usually: * Add an option to the linker command line that specify the hard-coded path the run-time linker should check for the lib (usually -R) * Set an environment variable (LD_LIBRARY_PATH for example) where ld.so should check for libs * Adjust the system's config to check for libs in the directory where you've put the dir (like Linux's /etc/ld.so.conf) 'man ld.so' and 'man ld' will tell you more details 5.9 How does libcurl resolve host names? libcurl supports a large a number of different name resolve functions. One of them is picked at build-time and will be used unconditionally. Thus, if you want to change name resolver function you must rebuild libcurl and tell it to use a different function. - The non-IPv6 resolver that can use one of four different host name resolve calls (depending on what your system supports): A - gethostbyname() B - gethostbyname_r() with 3 arguments C - gethostbyname_r() with 5 arguments D - gethostbyname_r() with 6 arguments - The IPv6-resolver that uses getaddrinfo() - The c-ares based name resolver that uses the c-ares library for resolves. Using this offers asynchronous name resolves. - The threaded resolver (default option on Windows). It uses: A - gethostbyname() on plain IPv4 hosts B - getaddrinfo() on IPv6 enabled hosts Also note that libcurl never resolves or reverse-lookups addresses given as pure numbers, such as 127.0.0.1 or ::1. 5.10 How do I prevent libcurl from writing the response to stdout? libcurl provides a default built-in write function that writes received data to stdout. Set the CURLOPT_WRITEFUNCTION to receive the data, or possibly set CURLOPT_WRITEDATA to a different FILE * handle. 5.11 How do I make libcurl not receive the whole HTTP response? You make the write callback (or progress callback) return an error and libcurl will then abort the transfer. 5.12 Can I make libcurl fake or hide my real IP address? No. libcurl operates on a higher level. Besides, faking IP address would imply sending IP packets with a made-up source address, and then you normally get a problem with receiving the packet sent back as they would then not be routed to you! If you use a proxy to access remote sites, the sites will not see your local IP address but instead the address of the proxy. Also note that on many networks NATs or other IP-munging techniques are used that makes you see and use a different IP address locally than what the remote server will see you coming from. You may also consider using https://www.torproject.org/ . 5.13 How do I stop an ongoing transfer? With the easy interface you make sure to return the correct error code from one of the callbacks, but none of them are instant. There is no function you can call from another thread or similar that will stop it immediately. Instead, you need to make sure that one of the callbacks you use returns an appropriate value that will stop the transfer. Suitable callbacks that you can do this with include the progress callback, the read callback and the write callback. If you're using the multi interface, you can also stop a transfer by removing the particular easy handle from the multi stack at any moment you think the transfer is done or when you wish to abort the transfer. 5.14 Using C++ non-static functions for callbacks? libcurl is a C library, it doesn't know anything about C++ member functions. You can overcome this "limitation" with relative ease using a static member function that is passed a pointer to the class: // f is the pointer to your object. static size_t YourClass::func(void *buffer, size_t sz, size_t n, void *f) { // Call non-static member function. static_cast(f)->nonStaticFunction(); } // This is how you pass pointer to the static function: curl_easy_setopt(hcurl, CURLOPT_WRITEFUNCTION, YourClass::func); curl_easy_setopt(hcurl, CURLOPT_WRITEDATA, this); 5.15 How do I get an FTP directory listing? If you end the FTP URL you request with a slash, libcurl will provide you with a directory listing of that given directory. You can also set CURLOPT_CUSTOMREQUEST to alter what exact listing command libcurl would use to list the files. The follow-up question tends to be how is a program supposed to parse the directory listing. How does it know what's a file and what's a dir and what's a symlink etc. If the FTP server supports the MLSD command then it will return data in a machine-readable format that can be parsed for type. The types are specified by RFC3659 section 7.5.1. If MLSD is not supported then you have to work with what you're given. The LIST output format is entirely at the server's own liking and the NLST output doesn't reveal any types and in many cases doesn't even include all the directory entries. Also, both LIST and NLST tend to hide unix-style hidden files (those that start with a dot) by default so you need to do "LIST -a" or similar to see them. Example - List only directories. ftp.funet.fi supports MLSD and ftp.kernel.org does not: curl -s ftp.funet.fi/pub/ -X MLSD | \ perl -lne 'print if s/(?:^|;)type=dir;[^ ]+ (.+)$/$1/' curl -s ftp.kernel.org/pub/linux/kernel/ | \ perl -lne 'print if s/^d[-rwx]{9}(?: +[^ ]+){7} (.+)$/$1/' If you need to parse LIST output in libcurl one such existing list parser is available at https://cr.yp.to/ftpparse.html Versions of libcurl since 7.21.0 also provide the ability to specify a wildcard to download multiple files from one FTP directory. 5.16 I want a different time-out! Time and time again users realize that CURLOPT_TIMEOUT and CURLOPT_CONNECTIMEOUT are not sufficiently advanced or flexible to cover all the various use cases and scenarios applications end up with. libcurl offers many more ways to time-out operations. A common alternative is to use the CURLOPT_LOW_SPEED_LIMIT and CURLOPT_LOW_SPEED_TIME options to specify the lowest possible speed to accept before to consider the transfer timed out. The most flexible way is by writing your own time-out logic and using CURLOPT_XFERINFOFUNCTION (perhaps in combination with other callbacks) and use that to figure out exactly when the right condition is met when the transfer should get stopped. 5.17 Can I write a server with libcurl? No. libcurl offers no functions or building blocks to build any kind of internet protocol server. libcurl is only a client-side library. For server libraries, you need to continue your search elsewhere but there exist many good open source ones out there for most protocols you could possibly want a server for. And there are really good stand-alone ones that have been tested and proven for many years. There's no need for you to reinvent them! 5.18 Does libcurl use threads? Put simply: no, libcurl will execute in the same thread you call it in. All callbacks will be called in the same thread as the one you call libcurl in. If you want to avoid your thread to be blocked by the libcurl call, you make sure you use the non-blocking API which will do transfers asynchronously - but still in the same single thread. libcurl will potentially internally use threads for name resolving, if it was built to work like that, but in those cases it'll create the child threads by itself and they will only be used and then killed internally by libcurl and never exposed to the outside. 6. License Issues Curl and libcurl are released under a MIT/X derivate license. The license is very liberal and should not impose a problem for your project. This section is just a brief summary for the cases we get the most questions. (Parts of this section was much enhanced by Bjorn Reese.) We are not lawyers and this is not legal advice. You should probably consult one if you want true and accurate legal insights without our prejudice. Note especially that this section concerns the libcurl license only; compiling in features of libcurl that depend on other libraries (e.g. OpenSSL) may affect the licensing obligations of your application. 6.1 I have a GPL program, can I use the libcurl library? Yes! Since libcurl may be distributed under the MIT/X derivate license, it can be used together with GPL in any software. 6.2 I have a closed-source program, can I use the libcurl library? Yes! libcurl does not put any restrictions on the program that uses the library. 6.3 I have a BSD licensed program, can I use the libcurl library? Yes! libcurl does not put any restrictions on the program that uses the library. 6.4 I have a program that uses LGPL libraries, can I use libcurl? Yes! The LGPL license doesn't clash with other licenses. 6.5 Can I modify curl/libcurl for my program and keep the changes secret? Yes! The MIT/X derivate license practically allows you to do almost anything with the sources, on the condition that the copyright texts in the sources are left intact. 6.6 Can you please change the curl/libcurl license to XXXX? No. We have carefully picked this license after years of development and discussions and a large amount of people have contributed with source code knowing that this is the license we use. This license puts the restrictions we want on curl/libcurl and it does not spread to other programs or libraries that use it. It should be possible for everyone to use libcurl or curl in their projects, no matter what license they already have in use. 6.7 What are my obligations when using libcurl in my commercial apps? Next to none. All you need to adhere to is the MIT-style license (stated in the COPYING file) which basically says you have to include the copyright notice in "all copies" and that you may not use the copyright holder's name when promoting your software. You do not have to release any of your source code. You do not have to reveal or make public any changes to the libcurl source code. You do not have to broadcast to the world that you are using libcurl within your app. All we ask is that you disclose "the copyright notice and this permission notice" somewhere. Most probably like in the documentation or in the section where other third party dependencies already are mentioned and acknowledged. As can be seen here: https://curl.haxx.se/docs/companies.html and elsewhere, more and more companies are discovering the power of libcurl and take advantage of it even in commercial environments. 7. PHP/CURL Issues 7.1 What is PHP/CURL? The module for PHP that makes it possible for PHP programs to access curl- functions from within PHP. In the cURL project we call this module PHP/CURL to differentiate it from curl the command line tool and libcurl the library. The PHP team however does not refer to it like this (for unknown reasons). They call it plain CURL (often using all caps) or sometimes ext/curl, but both cause much confusion to users which in turn gives us a higher question load. 7.2 Who wrote PHP/CURL? PHP/CURL was initially written by Sterling Hughes. 7.3 Can I perform multiple requests using the same handle? Yes - at least in PHP version 4.3.8 and later (this has been known to not work in earlier versions, but the exact version when it started to work is unknown to me). After a transfer, you just set new options in the handle and make another transfer. This will make libcurl re-use the same connection if it can. 7.4 Does PHP/CURL have dependencies? PHP/CURL is a module that comes with the regular PHP package. It depends on and uses libcurl, so you need to have libcurl installed properly before PHP/CURL can be used. usr/share/doc/pure-ftpd/FAQ000064400000077447152527274600011521 0ustar00 FREQUENTLY ASKED QUESTIONS -------------------------------------------------- * Users can delete root-owned files? -> I have a directory owned by 'john', but I've put some files owned by 'root' (or another user) in it. However, I noticed that John can delete these files! Yes, this is the standard Unix behavior: the owner of a directory can do whatever he likes to do in his directory, regardless of who owns the file in it. If you want to have immutable files, check for such a feature in your operating system. For instance, on Linux filesystems, "chattr +i " does the trick. On BSD systems, try "chflags schg " . * Directories shared by multiple users. -> I have a "public" directory. All users can download and upload files from/to this directory. Permissions are 777 on it. But user 'john' can delete files owned by user 'joe'. How to prevent this? Put the sticky bit on that directory: chmod 1777 public. That way, the directory remains public (read/write), but people can only delete files they own. * Restricting directory visibility. -> I want that people only see their home directory and their own files. I don't want them to look at my systems files. This feature is called "chroot". You can enable this by running pure-ftpd with the "-A" switch to do this with ALL your users (but root) . You can alternatively use "-a " to have a "trusted group". Everyone will be caged, EXCEPT members of that group. Don't use -a and -A together. Another way is to selectively choose what users you want to chroot. This can be done with the /./ trick (see the README file about this) or with virtual users. * Shared directories and chroot. -> I have a directory, say /var/incoming, that I want to be shared by every user. But I want my users to be chrooted. So /var/incoming should be visible in 'joe' and 'john' accounts, but those are chrooted. So, how to have the content of /var/incoming visible in these accounts? Making a symbolic link won't work, because when you are chrooted, it means that everything outside a base directory (your user's home directory) won't be reachable, even though a symbolic link. But all modern operating systems can mount local directories to several locations. To have an exact duplicate of your /var/incoming directory available in /home/john/incoming and /home/joe/incoming, use one of these commands: * Linux : mount --bind /var/incoming /home/john/incoming mount --bind /var/incoming /home/joe/incoming * Solaris : mount -F lofs /var/incoming /home/john/incoming mount -F lofs /var/incoming /home/joe/incoming * FreeBSD : mount_null /var/incoming /home/john/incoming mount_null /var/incoming /home/joe/incoming Another alternative is to compile Pure-FTPd with --with-virtualchroot as a ./configure option. With virtual chroot, symbolic links pointing outside a chroot jail *are* followed. Binary packages are compiled with this feature turned on. * Tar and/or gzip on the fly -> Is it possible to use a command like "get directory.tar" as with Wu-FTPd ? (Sven Goldt) Unfortunately, no. Server-side gzip/tar creation is not a present nor a planned feature. It has been responsible of severe security flaws in Wu-ftpd and BSD ftpd, it can take a lot of server resource (denial-of-service) and it's a pain to set up (chrooted environment => need to add /etc /lib /bin directories, /dev on some platforms, etc) . * How to restrict access to dot files ? -> Is there an option to prevent people from accessing "." files/dirs (such as .bash_history, .profile, .ssh ...) EVEN if they are owned by the user ? (William Kern) Yes. '-x' (--prohibitdotfileswrite) denies write/delete/chmod/rename of dot-files, even if they are owned by the user. They can be listed, though, because security through obscurity is dumb and software shouldn't lie to you. But users can't change the content of these files. Alternatively, you can use '-X' (--prohibitdotfilesread) to also prevent users from READING these files and going into directories that begin with "." . * Log files -> Where does logging info go ? How to redirect it to a specific file ? How to suppress logging ? Log messages are sent to the syslog daemon. The syslog daemon is often called syslogd or syslog-ng. He's in charge of dispatching logging events from various programs to log files, according to a "facility" (category) and a "priority" (urgency: debug, info, warning, error, critical...) . Pure-FTPd logging messages are send with the "ftp" facility by default (or "local2" on some older systems without the "ftp" facility) . Unless you told the syslogd to redirect messages with the "ftp" facility to a specific file, the messages will be merged into /var/adm/messages, /var/log/messages, /var/adm/syslog or /var/log/syslog. Check /etc/syslogd.conf. You should have a line like: *.*;mail.none;news.none -/var/log/messages just add ftp.none: *.*;ftp.none;mail.none;news.none -/var/log/messages And if you want FTP info go in a specific file, just add: ftp.* /var/log/ftp and all FTP messages will go in /var/log/ftp . And only there. The facility can be changed if you add the -f option to pure-ftpd (or --facility=) . To completely disable logging, use -f none (or --facility=none) . If you don't read your log files, it's recommended: it will improve performance and reduce disk I/O. * How to prevent your partitions to be filled -> Is it possible to forbid new uploads when the disk is almost full ? (Cyberic) Use the "-k" (--maxdiskusagepct) flag. If you add -k 95 , no new upload can occur if your partition if more than 95% full. * Firewalling -> My FTP server is behind a firewall. What ports should I open? First, you have to open port 21 TO the FTP server. You also have to allow connections FROM (not to) ports <= 20 (of the FTP server) to everywhere. That's enough to handle the "active" mode. But that's not enough to handle all types of clients. Most clients will use another mode to transmit data called 'passive' mode. It's a bit more secure than 'active' mode, but you need to open more ports on your firewall to have it work. So, open some ports TO the FTP server. These ports should be > 1023. It's recommended to use at least twice the max number of clients you are expecting. So, if you accept 200 concurrent sessions, opening ports 50000 to 50400 is ok. Then, run pure-ftpd with the '-p' switch followed by the range configured in your firewall. Example: /usr/local/sbin/pure-ftpd -p 50000:50400 & Unlike some popular belief, the MORE opened ports you have for passive FTP, the MORE your FTP server will be secure, because the LESS you are vulnerable to data hijacking. If your firewall also does network translation (NAT), you have to enable port forwarding for all passive ports. On the client side, if a client if behind a firewall, that firewall must understand the FTP protocol. On Linux firewalls (iptables), just load the ip_conntrack_ftp and ip_nat_ftp modules. On OpenBSD, ISOS and FreeBSD 5 firewalls (PF), redirect all traffic to port 21, to ftp-proxy. * Unable to log in (unix authentication) -> I'm using simple Unix authentication. No PAM, no puredb, no MySQL, no LDAP. Anonymous FTP works, but I can't log in as any other user. It keeps saying "authentication failed". To log in, the shell assigned to your users must be listed in the /etc/shells file. The exact path should be there, even for fake shells like /etc or /bin/true. Also double check that you have a carriage return after the last line in /etc/shells. * Network filesystems. -> I have a strange problem on Linux or FreeBSD. Uploading a file works fine, but downloading a file only create 0-byte files. On the server, these files are on NFS/Novell shares/Appletalk shares/Coda/Intermezzo/SMB volumes. By default, pure-ftpd uses zero-copy networking in order to increase throughput and reduce the CPU load. But zero-copy doesn't work with all filesystems, especially network filesystems. You have to disable zero-copy if you want to serve files from a network FS or from a TMPFS virtual disk. To disable zero-copy, recompile pure-ftpd with ./configure --without-sendfile * Solaris and chroot. -> When I ftp to my Solaris server, I get this as an answer to 'ls': "425 Can't create the data socket: Bad file number." On Solaris, to get chroot to work with pure-ftpd you need a dev directory in your new rootdir with these: crw-rw-rw- 1 root other 11, 42 Dec 10 15:02 tcp crw-rw-rw- 1 root other 105, 1 Dec 10 15:02 ticotsord crw-rw-rw- 1 root other 11, 41 Dec 10 15:03 udp crw-rw-rw- 1 root other 13, 12 Dec 10 15:03 zero (Reported by Kenneth Stailey) * Upgrading. -> Can anyone explain how to update Pureftpd (from source), without having to change all my settings etc. (Simon H) 1) get the source code and unpack it. 2) ./configure it with your favorite options 3) make 4) rm -f /usr/local/sbin/pure-ftpd 5) make install-strip 6) if you run pure-ftpd from inetd,tcpserver,xinetd, etc: nothing left to do. You have it upgraded. 7) if you run it standalone, stop the server: kill $(cat /var/run/pure-ftpd.pid) then launch it again: /usr/local/sbin/pure-ftpd & * FTP over SSH. -> How to run Pure-FTPd over SSH? I want to encrypt all connection data (including passwords) . FTP-over-SSH is a nice alternative over FTP-over-TLS (impossible to securely firewall) and SFTP (which is slower, but only uses one port) . Customers using Windows can use FTP-over-SSH with the excellent Van Dyke's SecureFX client (http://www.vandyke.com) . It doesn't require any special knowledge: just tell your customer to check "FTP-over-SSH2" in the "Protocol" listbox when creating an account for your FTP server. On the server side, here's how to manage FTP-over-SSH accounts: 1) Add /usr/bin/false to your /etc/shells file (on some systems, it's /bin/false) . 2) To create a FTP-over-SSH account, create a system account with /dev/null as a home directory and /usr/bin/false as a shell. You don't need a dedicated uid: the same uid can be reused for every FTP-over-SSH account. 3) Create a virtual user account for that user (either with PureDB, SQL or LDAP) . Give that virtual user a real home directory and only allow connections coming from 127.0.0.1 (all FTP-over-SSH sessions will come from localhost, due to SSH tunneling) . People with no home directory (/dev/null) and no valid shell (/usr/bin/false) won't be able to get a shell nor to run any command on your server. But they will be granted FTP-over-SSH sessions. Here are examples (Linux/OpenBSD/ISOS commands, translate them if necessary) . 1) Creating a regular FTP account: pure-pw useradd customer1 -m -d /home/customer1 -u ftpuser 2) Creating a FTP-over-SSH account (non-encrypted sessions are denied): useradd -u ftpuser -g ftpgroup -d /dev/null -s /usr/bin/false customer2 pure-pw useradd customer2 -m -d /home/customer2 -u ftpuser -r 127.0.0.1/32 3) Creating an account who can use regular (unencrypted) FTP from the internal network (192.168.1.x), but who must use FTP-over-SSH when coming from an external network (internet): useradd -u ftpuser -g ftpgroup -d /dev/null -s /usr/bin/false customer3 pure-pw useradd customer3 -m -d /home/customer3 -u ftpuser \ -r 127.0.0.1/32,192.168.1.0/24 * Virtual users: /etc/pureftpd.pdb . -> I made changes to /etc/pureftpd.passwd but the server doesn't understand them: I can't access any account I just created. The server never reads /etc/pureftpd.passwd directly. Instead, it reads /etc/pureftpd.pdb (or whatever file name you gave after -lpuredb:...) . This file is a copy of /etc/pureftpd.passwd, but in a binary format, optimized for fast lookups. After having made a manual change to /etc/pureftpd.passwd, you must rebuild /etc/pureftpd.pdb with the following commands: pure-pw mkdb If you add/delete/modify user accounts with pure-pw useradd/usermod/userdel/ passwd, don't forget the '-m' option to automatically rebuild /etc/pureftpd.pdb and not only update /etc/pureftpd.passwd . * Giving access to dot-files. -> I don't want my users to read files beginning with a dot. Except one file I'd like to give 'John' read (and maybe write) access to. Create a symbolic link in John's account, pointing to the dot-file. Example: ln -s .bashrc bashrc John will be able to access ".bashrc" through the symbolic link, "bashrc". * Initial banner. -> How do I display a customized message before the login prompt? Compile with --with-cookie and run the server with -F . In that file, put a nice customized banner message. * Internet Explorer. -> Internet Explorer doesn't show any login box. IE does a very strange trick to detect whether an FTP server does accept anonymous connections or not. Basically, it connects to the server and logs in as 'anonymous'. But if you say 'no' at this point, it drops the connections with an error. You have to say 'ok, anonymous users are allowed' and then, when a dummy password ('IE@') is sent, you say 'ah ehm... finally... no... anonymous users aren't allowed' . Silly. To play that game, you must run pure-ftpd with the -E (non-anonymous server) and -b (compatibility with broken clients) flags. Then, the magic popup will show up. But please note that IE (and browsers at large) are usually bad FTP clients. -> Internet Explorer doesn't want to log in. (Matthew Enger) Check that the max number of connections (either per user or per IP) is at least 2. IE needs two connections to connect to an FTP server. * Passwords and pure-pw scripting. -> I would like to create virtual users with a shell-script. if i us pure-pw useradd ..... it always asks for the new password. is there any command-line option which tells pure-pw the password (like useradd ftp-user ftp-password -m) ? (at1ce) . Giving cleartext (and badly one-way hashed) passwords through command-line switches is a bad idea. Because users could issue a simple 'ps' command and discover these passwords. One way to enter a password (not from the keyboard) is to put the password twice in a temporary file, then redirect that file to stdin. Example: pure-pw useradd john -d /tmp/john -u ftpuser -m < ~/tmp/passfile And in ~/tmp/passfile, have something like: john's password john's password If you really need to avoid a temporary file and if nobody but you can log on the machine, you can always do this: (echo blahblah; echo blahblah) | pure-pw useradd john -d /tmp/john -u ftpuser * Altlog and pure-uploadscript don't work. -> pure-uploadscript doesn't run anything. Alternative logging methods (CLF, stats, W3C...) create a logfile, but it always stays empty. Maybe your operating system has a buggy realpath() implementation. Some old Solaris and Linux versions are known to have such a bug. Try to recompile pure-ftpd, but run ./configure with the --with-brokenrealpath switch first. * The server starts, but doesn't listen to any port? -> The server is properly running, I see it in the process list, but any try to connect to the configured port (or port 21 by default) fails. The socket isn't even open. Check two things : - If you are running a BSD system and you want to listen to IPv4 addresses, check that the "-4" switch ("IPV4Only" in config file) is enabled. - If you upload script are enabled ("-o", or "CallUploadScript"), make sure that the pure-uploadscript is started. Or the FTP server will actually wait until pure-uploadscript is actually ready to process new uploads. If you don't need the uploadscript facility, remove "-o". * Double slash. -> Why do I see double slashes in log files? For instance, the path of a downloaded file looks like /home/john//pictures/zok.jpg . '//' is a symbol for the limit of the chroot jail. In that example, it means that John is caged in /home/john/ . * ftpwho as a non-root user. -> How do I give access to the 'pure-ftpwho' command to non-root users? The 'pure-ftpwho' command is restricted to root by default, because users probably shouldn't be given the ability to spy what other users are doing on the same host. However, it's safe to put the setuid bit on that command, in order to have it work as any user: chmod 4711 /usr/local/sbin/pure-ftpwho * Changing bandwidth throttling on-the-fly. -> Is it possible to change the bandwidth allocated to a user during a transfer, so that the change takes place immediately? Unfortunately, no. Or at least not at pure-ftpd level. Doing so would need to re-read user's parameters all the time and it would be horribly slow. Other mechanisms would work, like signals to interrupt transfers, re-read parameters, then resume. But it would introduce a lot of complexity to the code. If you're using a modern operating system like OpenBSD, ISOS or Linux, your kernel already includes a fair TCP/IP traffic shaper. And because it works at kernel-level, you can easily change the bandwidth allowed to IPs or services on-the-fly. Have a look at pf.conf(5) OpenBSD, ISOS and FreeBSD 5, and at tc (or read the Linux networking HOWTO) on Linux. Also see the 'Global bandwidth limitation' section later in this document. * KERBEROS_V4 rejected as an authentication type. -> It works and I can log in, but I receive these strange error messages at log in, even in a non-chrooted environment: 220 FTP server ready. 502 Security extensions not implemented 502 Security extensions not implemented KERBEROS_V4 rejected as an authentication type Why and what do they mean? This is a Linux-specific instllation issue. It means that your command-line FTP client isn't a normal one, but a Kerberos FTP client. You probably installed RPMs for Kerberos, although you don't use it. These messages are harmless as Kerberos clients will fallback to normal FTP (after these errors), but you just have to deinstall Kerberos on your client host to have 'ftp' work without these messages. * Wrong group ownership. -> I have a user called 'john' whose group is 'johngroup'. When John uploads a file, that one belongs to 'john', but to another group like 'wheel' (whose John isn't a member of). What's wrong? This is a BSD standard behavior (verified on OpenBSD, ISOS, DragonflyBSD and FreeBSD): when a new file is created, the group is inherited from the parent directory. On other systems (like GNU/Linux), files are owned by the primary group of the user, unless the directory has the setgid bit set. If you want new files uploaded in John's directory to belong to group 'johngroup', have that directory (and probably also subdirectories) belong to 'johngroup': chgrp -R johngroup /home/john * Compilation with MySQL. -> I can't compile with MySQL. ./configure says that MySQL libraries aren't properly installed. The libmysqlclient.so file should be in a path known by your dynamic linker. For instance, on a GNU/Linux system, add the path to libmysqlclient.so file (only the path, not the file itself) to /etc/ld.so.conf . Then, run 'ldconfig' . * "Sorry, I can't trust you". -> When a user tries to log in, he gets "Sorry, I can't trust you". But his login/password pair is right. What wrong? That message can means two things: - The user has a shell that isn't listed in /etc/shells. You must add it, even if it's a fake shell like /bin/false . Also make sure that you have a carriage return after the last entry in /etc/shells. - You are using the -u option to deny access to users whose uid is below . But the user you are trying to log in as, has an uid in the forbidden range. * Customer-friendly configuration. -> What switches do you recommend to start the server, for an hosting service? Here's a good start: --chrooteveryone \ --maxclientsperip=5 \ --displaydotfiles \ --noanonymous \ --minuid=100 \ --umask=022:022 \ --limitrecursion=10000:3 \ --customerproof * Anonymous FTP with virtual users. -> I successfully created a virtual user called 'ftp' or 'anonymous', but anonymous FTP doesn't work. Pure-FTPd never fetch any info from the virtual users backends (puredb, MySQL, LDAP, etc) for anonymous sessions. There are three reasons not to do so: - Speed: do we need to query a database just to get the anonymous user's home directory? We don't need to retrieve any password for anonymous sessions. - Consistency: with the virtual hosting mechanism. To run an anonymous FTP server you must have a *system* account called 'ftp'. Don't give it any valid shell, just a home directory. That home directory is the anonymous area. * A basic setup. -> I'm trying to set up a ftp server just for me and my family so we can get and upload files when on the road. How can I make two users, say Jane and Joe, who share the directory /home/ftp and /home/ftp/incoming. In /home/ftp they only have read privs. and in /home/ftp/incoming they have read and write privs. Add a group for all FTP users (not mandatory, but more secure): groupadd ftpgroup Add an uid for all FTP users (idem, not mandatory, but better): useradd -g ftpgroup -d /dev/null -s /etc ftpuser Now, let's create /home/ftp and /home/ftp/incoming: mkdir -p /home/ftp/incoming chown -R root:ftpgroup /home/ftp/incoming chmod -R 755 /home/ftp chmod -R 1775 /home/ftp/incoming Let's add Jane: pure-pw useradd jane -m -u ftpuser -d /home/ftp Let's add Joe: pure-pw useradd joe -m -u ftpuser -d /home/ftp Let's start the FTP server: /usr/local/sbin/pure-ftpd -lpuredb:/etc/pureftpd.pdb -H -B Everything should be ok now. For more info about how to create new users, change passwords, etc.: http://www.pureftpd.org/README.Virtual-Users * Slow pure-ftpwho or slow login. -> Sometimes, pure-ftpwho is slow to show the result. And sometimes, when an user logs in, the session stucks a bit before he can get a directory listing. This is probably caused by a slow DNS resolver. In order to display full host names, pure-ftpd has indeed to make DNS queries that can be slow if you link is slow, or if the client link is slow. You can speed up pure-ftpwho and pure-ftpd with the -H switch. Names won't be resolved, you will see IP addresses instead. * Chrooted users can follow symlinks outside the chroot jail? -> People can create symbolic links to '/' and escape their home directory! There are two chroot implementations in pure-ftpd: - The traditional one, based upon your kernel chroot() system call. This is the default. With that one, symbolic links can only point inside the chroot jail, or they won't be followed. - The 'virtual chroot' implementation. With that feature, users *can* follow all symbolic links, even when they don't point inside the jail. This is very handy to set up directories shared by multiple users. Binary packages are compiled with virtual chroot by default. To enable the virtual chroot feature when you are compiling the server, use the --with-virtualchroot with ./configure . If you want a restricted chroot, don't include --with-virtualchroot. Please note that the FTP server will never let people create new symbolic links. Symbolic links have to be already there to be followed. Or if your users can create symbolic links through Perl or PHP scripts, your hosting platform is really badly configured. People can install any web file browser, they don't need FTP to look at your system files. Recompile PHP without POSIX functions and run all Perl scripts chrooted. * How to start Pure-FTPd in background. -> I start 'pure-ftpd' from an X terminal and the server properly answers. However, as soon as I close the terminal, the server stops. This is a shell dependent issue. Your shell is configured to close all background jobs when leaving. You can change your shell options (probably with a 'set' directive) or detach background jobs with the 'disown' keyword. Alternatively, you can just start pure-ftpd with the -B switch in order to have it detach at startup time: /usr/local/sbin/pure-ftpd -B * Windows command-line FTP client and 'ls'. -> With the command-line Windows FTP client, 'ls -la' doesn't return any file. The 'ls' command of an FTP client has nothing to do with the 'ls' command started from an Unix shell. With the command-line Windows client, typing 'ls' really sends the FTP command 'NLST'. So when you type 'ls -la', it doesn't mean 'verbosely list all files'. According to RFCs, it means 'list the file called -la' . So you get what you asked for. If no file is called '-la', you get nothing. If you want to play with regular expressions and switches, you should type 'dir' (which is translated to 'LIST') instead. 'dir -la' is ok. This is a bit illogical and that brain damage is specific to Microsoft's command-line FTP client. If you really want 'ls' to parse options, you can start pure-ftpd with the -b (broken) switch. * Global bandwidth limitation. -> How do I limit the *total* bandwidth for FTP? Pure-FTPd can limit bandwidth usage of every session. But limiting the total bandwidth is intentionally not implemented, because most operating systems already have very efficient algorithms to handle bandwidth throttling. Here's an example with Linux. 1) Have a look at /proc/sys/net/ipv4/ip_local_port_range. You will see two numbers: this is the interval of local ports your Linux kernel will use for regular outgoing connections. The FTP ports you have to reserve for passive FTP must *not* be in this range. So if: "cat /proc/sys/net/ipv4/ip_local_port_range" returns "32768-61000", you can reserve ports 10000 to 20000 for your FTP server, but not 30000 to 40000. (alternatively, you can change the local port range) . 2) Change the first lines and save the following script: ---------------------------- Cut here ---------------------------- #! /bin/sh # Simple bandwidth limiter - # Change this to your link bandwidth # (for cable modem, DSL links, etc. put the maximal bandwidth you can # get, not the speed of a local Ethernet link) REAL_BW='10Mbit' # Change this to the bandwidth you want to allocate to FTP. # We're talking about megabits, not megabytes, so 80Kbit is # 10 Kilobytes/s FTP_BW='80Kbit' # Change this to your physical network device (or 'ppp0') NIC='eth0' # Change this to the ports you assigned for passive FTP FTP_PORT_LOW="10000" FTP_PORT_HIGH="20000" tc qdisc add dev "$NIC" root handle 1: cbq \ bandwidth "$REAL_BW" avpkt 1000 tc class add dev "$NIC" parent 1: classid 1:1 cbq bandwidth "$REAL_BW" \ rate "$REAL_BW" maxburst 5 avpkt 1000 tc class add dev "$NIC" parent 1:1 classid 1:10 cbq \ bandwidth "$REAL_BW" rate "$FTP_BW" maxburst 5 avpkt 1000 bounded tc qdisc add dev "$NIC" parent 1:10 sfq quantum 1514b tc filter add dev "$NIC" parent 1: protocol ip handle 1 fw flowid 1:10 iptables -t mangle -A OUTPUT -p tcp --sport 20:21 -j MARK --set-mark 1 iptables -t mangle -A OUTPUT -p tcp \ --sport "$FTP_PORT_LOW":"$FTP_PORT_HIGH" -j MARK --set-mark 1 ---------------------------- Cut here ---------------------------- 3) Make sure that you have the 'tc' command installed. If your Linux distro doesn't ship 'ip' and 'tc' commands, it really sucks and you must install a package called 'iproute2' to get them. 4) Start Pure-FTPd with the passive port range you assigned: /usr/local/sbin/pure-ftpd -p 10000:20000 -HBA 5) Run the script you created in step 2. It it doesn't work, check that QOS support was compiled in your Linux kernel. 6) Enjoy :) Also have a look at : http://www.docum.org http://www.shorewall.net/traffic_shaping.htm and http://talk.trekweb.com/~jasonb/articles/linux_tc_minihowto.shtml * Linux, NTFS and Pure-FTPd. -> On Linux, I can't transfer files from an NTFS partition. Keep in mind that the NTFS filesystem is still an experimental beast in Linux. Some basic operations are not implemented yet. Fortunately, a big effort is being made and Linux 2.5 has a new NTFS implementation that fully works with Pure-FTPd (try ./configure --without-sendfile, though) . And it is more reliable and really faster than the old one. And even more fortunately, the new NTFS implementation has been backported to recent 2.4.x kernels. Have a look at http://linux-ntfs.sf.net/ . * Slowdowns and lags. -> Some users complains that transferring large files doesn't work. Transfers are starting as expected, with a decent rate. But then, the speed dramatically decreases, there are some serious lags and they often must disconnect (or the client force them to do it, after a timeout) . The server is behind a firewall that filters incoming ICMP, but let FTP ports in. Don't, don't, don't filter ICMP. At least not blindly without understanding what you are filtering. ICMP is part of the TCP/IP specifications. Filtering it can have nasty side effects with no real win. If you even filter ICMP types 3 and 4, your firewall is definitely broken and this is probably why you have such troubles with transfers of large files. Please read these documents about ICMP filtering : http://www.phildev.net/mss/index.html http://alive.znep.com/~marcs/mtu/ http://www.freelabs.com/~whitis/isp_mistakes.html Also some hardware routers don't properly handle window scaling. Try to turn it off, for instance on Linux: sysctl -w net.ipv4.tcp_window_scaling=0 sysctl -w net.ipv4.tcp_bic=0 * Firewalls and TLS. -> My client is behind a stateful firewall doing applicative filtering (like IPTables with ip_conntrack_ftp or ip_nat_ftp) . Connections to an TLS enabled server doesn't work. Authentication works, but I'm unable to download files nor list directories. First, try to force your client to use the passive mode. In active mode, the server has to connect to the client (or the NAT gateway) on a dynamic port that is negotiated on the connection socket. But when TLS is used, that connection socket is encrypted, therefore no man-in-the middle can see what ports will be used to transfer data, including the firewall. There are some proposals to work around this problem, but neither popular clients nor common firewalls are aware of these tricks. Therefore, use the passive mode or switch to SSH. * TLS and error 00000000. -> My TLS-enabled client doesn't work. It outputs something like : "SSL connect: error:00000000:lib(0):func(0):reason(0)". What does it mean? This error is not very explicit. You get it from some Unix clients like LFTP. It actually means that there is a firewall or a NAT box between a TLS-enabled server and a TLS-enabled client, but that firewall is unable to handle encrypted FTP sessions. Unfortunately, there's no simple workaround against this. Try to switch your client to active mode and use 1:1 NAT, but TLS, firewalls and FTP don't mix very well. * Slow TLS operations. -> When clients connect with TLS encryption, listing directories and downloading files are slow operations. Nothing happens after a command is sent, things only start moving after a 5 secondes delay. Check the host name of your certificate. It should be a fully-qualified host name and if possible, it shouldn't be a CNAME entry. Also check your DNS cache servers. * Files getting renamed automatically (submitted by C. Jon Larsen) -> Sometimes when files get uploaded they are getting renamed to something like "pureftpd.3f3300d2.33.0001". What is causing this ? The ftp client that is being used to upload the files is using the STOU (Store Unique) FTP command instead of the STOR FTP command. If you check the ftp logfile you should see something like this in the logs: (user@a.b.c.d) [DEBUG] Command [stou] [file_name_from_the_client.ext] /var/ftp/ftpcustomer/pureftpd.3f3300d2.33.0001 uploaded (218168 bytes, 127.79KB/sec) The STOU command tells the ftp client to begin the transmission of the file to the remote site; the remote filename picked by the ftp server will be unique within in the current directory that the ftp client is using. The response from the server will include the filename. The ftp client has an option like "create unique files" or "upload file with a temporary name" enabled. You should have the ftp user uncheck this option. Trying to disable the STOU command on the server side is not a good idea or solution as some ftp clients will use STOU to upload a file with the temporary, unique name, and then rename the file once the upload is complete. This helps prevent failed uploads from leaving partial files around. usr/share/doc/chrony/FAQ000064400000155304152530070540011071 0ustar00Frequently Asked Questions Table of Contents o 1. chrony compared to other programs ? 1.1. How does chrony compare to ntpd? ? 1.2. Should I prefer chrony over timesyncd if I do not need to run a server? o 2. Configuration issues ? 2.1. What is the minimum recommended configuration for an NTP client? ? 2.2. How do I make an NTP server? ? 2.3. Should all computers on a LAN be clients of an external server? ? 2.4. Must I specify servers by IP address if DNS is not available on chronyd start? ? 2.5. How can I make chronyd more secure? ? 2.6. How can I make the system clock more secure? ? 2.7. How can I improve the accuracy of the system clock with NTP sources? ? 2.8. Does chronyd have an ntpdate mode? ? 2.9. Can chronyd be configured to control the clock like ntpd? ? 2.10. Can NTP server be separated from NTP client? ? 2.11. How can chronyd be configured to minimise downtime during restarts? ? 2.12. Should be a leap smear enabled on NTP server? ? 2.13. How should chronyd be configured with gpsd? ? 2.14. Does chrony support PTP? ? 2.15. How can I avoid using wrong PHC refclock? ? 2.16. Why are client log records dropped before reaching clientloglimit? ? 2.17. What happened to the commandkey and generatecommandkey directives? o 3. Computer is not synchronising ? 3.1. Behind a firewall? ? 3.2. Are NTP servers specified with the offline option? ? 3.3. Is name resolution working correctly? ? 3.4. Is chronyd allowed to step the system clock? ? 3.5. Using NTS? ? 3.6. Using a Windows NTP server? ? 3.7. An unreachable source is selected? ? 3.8. Does selected source drop new measurements? ? 3.9. Using a PPS reference clock? o 4. Issues with chronyc ? 4.1. I keep getting the error 506 Cannot talk to daemon ? 4.2. I keep getting the error 501 Not authorised ? 4.3. What is the reference ID reported by the tracking command? ? 4.4. Is the chronyc / chronyd protocol documented anywhere? o 5. Real-time clock issues ? 5.1. What is the real-time clock (RTC)? ? 5.2. Does hwclock have to be disabled? ? 5.3. I just keep getting the 513 RTC driver not running message ? 5.4. I get Could not open /dev/rtc, Device or resource busy in my syslog file ? 5.5. When I start chronyd, the log says Could not enable RTC interrupt : Invalid argument (or it may say disable) ? 5.6. What if my computer does not have an RTC or backup battery? o 6. NTP-specific issues ? 6.1. Can chronyd be driven from broadcast/multicast NTP servers? ? 6.2. Can chronyd transmit broadcast NTP packets? ? 6.3. Can chronyd keep the system clock a fixed offset away from real time? ? 6.4. What happens if the network connection is dropped without using chronyc's offline command first? ? 6.5. Why is an offset measured between two computers synchronised to each another? o 7. Operation ? 7.1. What clocks does chronyd use? o 8. Operating systems ? 8.1. Does chrony support Windows? ? 8.2. Are there any plans to support Windows? 1. chrony compared to other programs 1.1. How does chrony compare to ntpd? chrony and ntpd are two different implementations of the Network Time Protocol (NTP). chrony is a newer implementation, which was designed to work well in a wider range of conditions. It can usually synchronise the system clock faster and with better time accuracy. It has many features, but it does not implement some of the less useful NTP modes like broadcast client or multicast server/client. If your computer is connected to the Internet only for few minutes at a time, the network connection is often congested, you turn your computer off or suspend it frequently, the clock is not very stable (e.g. there are rapid changes in the temperature or it is a virtual machine), or you want to use NTP on an isolated network with no hardware reference clocks in sight, chrony will probably work better for you. For a more detailed comparison of features and performance, see the comparison page on the chrony website. 1.2. Should I prefer chrony over timesyncd if I do not need to run a server? Generally, yes. systemd-timesyncd is a very simple NTP client included in the systemd suite. It lacks almost all features of chrony and other advanced client implementations listed on the comparison page. One of its main limitations is that it cannot poll multiple servers at the same time and detect servers having incorrect time (falsetickers in the NTP terminology). It should be used only with trusted reliable servers, ideally in local network. Using timesyncd with pool.ntp.org is problematic. The pool is very robust as a whole, but the individual servers run by volunteers cannot be relied on. Occasionally, servers drift away or make a step to distant past or future due to misconfiguration, problematic implementation, and other bugs (e.g. in firmware of a GPS receiver). The pool monitoring system detects such servers and quickly removes them from the pool DNS, but clients like timesyncd cannot recover from that. They follow the server as long as it claims to be synchronised. They need to be restarted in order to get a new address from the pool DNS. Note that the complexity of NTP and clock synchronisation is on the client side. The amount of code in chrony specific to NTP server is very small and it is disabled by default. If it was removed, it would not significantly reduce the amount of memory or storage needed. 2. Configuration issues 2.1. What is the minimum recommended configuration for an NTP client? First, the client needs to know which NTP servers it should ask for the current time. They are specified by the server or pool directive. The pool directive is used with names that resolve to multiple addresses of different servers. For reliable operation, the client should have at least three servers. The iburst option enables a burst of requests to speed up the initial synchronisation. To stabilise the initial synchronisation on the next start, the estimated drift of the system clock is saved to a file specified by the driftfile directive. If the system clock can be far from the true time after boot for any reason, chronyd should be allowed to correct it quickly by stepping instead of slewing, which would take a very long time. The makestep directive does that. In order to keep the real-time clock (RTC) close to the true time, so the system time is reasonably close to the true time when it is initialised on the next boot from the RTC, the rtcsync directive enables a mode in which the system time is periodically copied to the RTC. It is supported on Linux and macOS. If you wanted to use public NTP servers from the pool.ntp.org project, the minimal chrony.conf file could be: pool pool.ntp.org iburst driftfile /var/lib/chrony/drift makestep 1 3 rtcsync 2.2. How do I make an NTP server? By default, chronyd does not operate as an NTP server. You need to add an allow directive to the chrony.conf file in order for chronyd to open the server NTP port and respond to client requests. allow 192.168.1.0/24 An allow directive with no specified subnet allows access from all IPv4 and IPv6 addresses. 2.3. Should all computers on a LAN be clients of an external server? It depends on the requirements. Usually, the best configuration is to make one computer the server, with the others as clients of it. Add a local directive to the server's chrony.conf file. This configuration will be better because o the load on the external connection is less o the load on the external NTP server(s) is less o if your external connection goes down, the computers on the LAN will maintain a common time with each other. 2.4. Must I specify servers by IP address if DNS is not available on chronyd start? No, chronyd will keep trying to resolve the names specified by the server, pool, and peer directives in an increasing interval until it succeeds. The online command can be issued from chronyc to force chronyd to try to resolve the names immediately. 2.5. How can I make chronyd more secure? If you do not need to use chronyc, or you want to run chronyc only under the root or chrony user (which can access chronyd through a Unix domain socket), you can disable the IPv4 and IPv6 command sockets (by default listening on localhost) by adding cmdport 0 to the configuration file. You can specify an unprivileged user with the -u option, or the user directive in the chrony.conf file, to which chronyd will switch after start in order to drop root privileges. The configure script has a --with-user option, which sets the default user. On Linux, chronyd needs to be compiled with support for the libcap library. On other systems, chronyd forks into two processes. The child process retains root privileges, but can only perform a very limited range of privileged system calls on behalf of the parent. Also, if chronyd is compiled with support for the Linux secure computing (seccomp) facility, you can enable a system call filter with the -F option. It will significantly reduce the kernel attack surface and possibly prevent kernel exploits from the chronyd process if it is compromised. It is recommended to enable the filter only when it is known to work on the version of the system where chrony is installed as the filter needs to allow also system calls made from libraries that chronyd is using (e.g. libc) and different versions or implementations of the libraries might make different system calls. If the filter is missing some system call, chronyd could be killed even in normal operation. 2.6. How can I make the system clock more secure? An NTP client synchronising the system clock to an NTP server is susceptible to various attacks, which can break applications and network protocols relying on accuracy of the clock (e.g. DNSSEC, Kerberos, TLS, WireGuard). Generally, a man-in-the-middle (MITM) attacker between the client and server can o make fake responses, or modify real responses from the server, to create an arbitrarily large time and frequency offset, make the server appear more accurate, insert a leap second, etc. o delay the requests and/or responses to create a limited time offset and temporarily also a limited frequency offset o drop the requests or responses to prevent updates of the clock with new measurements o redirect the requests to a different server The attacks can be combined for a greater effect. The attacker can delay packets to create a significant frequency offset first and then drop all subsequent packets to let the clock quickly drift away from the true time. The attacker might also be able to control the server's clock. Some attacks cannot be prevented. Monitoring is needed for detection, e.g. the reachability register in the sources report shows missing packets. The extent to which the attacker can control the client's clock depends on its configuration. Enable authentication to prevent chronyd from accepting modified, fake, or redirected packets. It can be enabled with a symmetric key specified by the key option, or Network Time Security (NTS) by the nts option (supported since chrony version 4.0). The server needs to support the selected authentication mechanism. Symmetric keys have to be configured on both client and server, and each client must have its own key (one per server). The maximum offset that the attacker can insert in an NTP measurement by delaying packets can be limited by the maxdelay option. The default value is 3 seconds. The measured delay is reported as the peer delay in the ntpdata report and measurements log. Set the maxdelay option to a value larger than the maximum value that is normally observed. Note that the delay can increase significantly even when not under an attack, e.g. when the network is congested or the routing has changed. The maximum accepted change in time offset between clock updates can be limited by the maxchange directive. Larger changes in the offset will be ignored or cause chronyd to exit. Note that the attacker can get around this limit by splitting the offset into multiple smaller offsets and/or creating a large frequency offset. When this directive is used, chronyd will have to be restarted after a successful attack. It will not be able to recover on its own. It must not be restarted automatically (e.g. by the service manager). The impact of a large accepted time offset can be reduced by disabling clock steps, i.e. by not using the makestep and initstepslew directives. The offset will be slowly corrected by speeding up or slowing down the clock at a rate which can be limited by the maxslewrate directive. Disabling clock steps completely is practical only if the clock cannot gain a larger error on its own, e.g. when the computer is shut down or suspended, and the maxslewrate limit is large enough to correct an expected error in an acceptable time. The rtcfile directive with the -s option can be used to compensate for the RTC drift. A more practical approach is to enable makestep for a limited number of clock updates (the 2nd argument of the directive) and limit the offset change in all updates by the maxchange directive. The attacker will be able to make only a limited step and only if the attack starts in a short window after booting the computer, or when chronyd is restarted without the -R option. The frequency offset can be limited by the maxdrift directive. The measured frequency offset is reported in the drift file, tracking report, and tracking log. Set maxdrift to a value larger than the maximum absolute value that is normally observed. Note that the frequency of the clock can change due to aging of the crystal, differences in calibration of the clock source between reboots, migrated virtual machine, etc. A typical computer clock has a drift smaller than 100 parts per million (ppm), but much larger drifts are possible (e.g. in some virtual machines). Use only trusted servers, which you expect to be well configured and managed, using authentication for their own servers, etc. Use multiple servers, ideally in different locations. The attacker will have to deal with a majority of the servers in order to pass the source selection and update the clock with a large offset. Use the minsources directive to increase the required number of selectable sources to make the selection more robust. Do not specify servers as peers. The symmetric mode is less secure than the client/server mode. If not authenticated, it is vulnerable to off-path denial-of-service attacks, and even when it is authenticated, it is still susceptible to replay attacks. Mixing of authenticated and unauthenticated servers should generally be avoided. If mixing is necessary (e.g. for a more accurate and stable synchronisation to a closer server which does not support authentication), the authenticated servers should be configured as trusted and required to not allow the unauthenticated servers to override the authenticated servers in the source selection. Since chrony version 4.0, the selection options are enabled in such a case automatically. This behaviour can be disabled or modified by the authselectmode directive. An example of a client configuration limiting the impact of the attacks could be server ntp1.example.net iburst nts maxdelay 0.1 server ntp2.example.net iburst nts maxdelay 0.2 server ntp3.example.net iburst nts maxdelay 0.05 server ntp4.example.net iburst nts maxdelay 0.1 server ntp5.example.net iburst nts maxdelay 0.1 minsources 3 maxchange 100 0 0 makestep 0.001 1 maxdrift 100 maxslewrate 100 driftfile /var/lib/chrony/drift ntsdumpdir /var/lib/chrony rtcsync 2.7. How can I improve the accuracy of the system clock with NTP sources? Select NTP servers that are well synchronised, stable and close to your network. It is better to use more than one server. Three or four is usually recommended as the minimum, so chronyd can detect servers that serve false time and combine measurements from multiple sources. If you have a network card with hardware timestamping supported on Linux, it can be enabled by the hwtimestamp directive. It should make local receive and transmit timestamps of NTP packets much more stable and accurate. The server directive has some useful options: minpoll, maxpoll, polltarget, maxdelay, maxdelayratio, maxdelaydevratio, xleave, filter. The first three options set the minimum and maximum allowed polling interval, and how should be the actual interval adjusted in the specified range. Their default values are 6 (64 seconds) for minpoll, 10 (1024 seconds) for maxpoll and 8 (samples) for polltarget. The default values should be used for general servers on the Internet. With your own NTP servers, or if you have permission to poll some servers more frequently, setting these options for shorter polling intervals might significantly improve the accuracy of the system clock. The optimal polling interval depends mainly on two factors, stability of the network latency and stability of the system clock (which mainly depends on the temperature sensitivity of the crystal oscillator and the maximum rate of the temperature change). Generally, if the sourcestats command usually reports a small number of samples retained for a source (e.g. fewer than 16), a shorter polling interval should be considered. If the number of samples is usually at the maximum of 64, a longer polling interval might work better. An example of the directive for an NTP server on the Internet that you are allowed to poll frequently could be server ntp.example.net minpoll 4 maxpoll 6 polltarget 16 An example using shorter polling intervals with a server located in the same LAN could be server ntp.local minpoll 2 maxpoll 4 polltarget 30 The maxdelay options are useful to ignore measurements with an unusually large delay (e.g. due to congestion in the network) and improve the stability of the synchronisation. The maxdelaydevratio option could be added to the example with local NTP server server ntp.local minpoll 2 maxpoll 4 polltarget 30 maxdelaydevratio 2 If your server supports the interleaved mode (e.g. it is running chronyd), the xleave option should be added to the server directive to enable the server to provide the client with more accurate transmit timestamps (kernel or preferably hardware). For example: server ntp.local minpoll 2 maxpoll 4 xleave When combined with local hardware timestamping, good network switches, and even shorter polling intervals, a sub-microsecond accuracy and stability of a few tens of nanoseconds might be possible. For example: server ntp.local minpoll 0 maxpoll 0 xleave hwtimestamp eth0 For best stability, the CPU should be running at a constant frequency (i.e. disabled power saving and performance boosting). Energy-Efficient Ethernet (EEE) should be disabled in the network. The switches should be configured to prioritize NTP packets, especially if the network is expected to be heavily loaded. The dscp directive can be used to set the Differentiated Services Code Point in transmitted NTP packets if needed. If it is acceptable for NTP clients in the network to send requests at a high rate, a sub-second polling interval can be specified. A median filter can be enabled in order to update the clock at a reduced rate with more stable measurements. For example: server ntp.local minpoll -6 maxpoll -6 filter 15 xleave hwtimestamp eth0 minpoll -6 Since chrony version 4.3, the minimum minpoll is -7 and a filter using a long-term estimate of a delay quantile can be enabled by the maxdelayquant option to replace the default maxdelaydevratio filter, which is sensitive to outliers corrupting the minimum delay. For example: server ntp.local minpoll -7 maxpoll -7 filter 31 maxdelayquant 0.3 xleave Since version 4.2, chronyd supports an NTPv4 extension field containing an additional timestamp to enable frequency transfer and significantly improve stability of synchronisation. It can be enabled by the extfield F323 option. For example: server ntp.local minpoll 0 maxpoll 0 xleave extfield F323 Since version 4.5, chronyd can apply corrections from PTP one-step end-to-end transparent clocks (e.g. network switches) to significantly improve accuracy of synchronisation in local networks. It requires the PTP transport to be enabled by the ptpport directive, HW timestamping, and the extfield F324 option. For example: server ntp.local minpoll -4 maxpoll -4 xleave extfield F323 extfield F324 port 319 ptpport 319 hwtimestamp eth0 minpoll -4 2.8. Does chronyd have an ntpdate mode? Yes. With the -q option chronyd will set the system clock once and exit. With the -Q option it will print the measured offset without setting the clock. If you do not want to use a configuration file, NTP servers can be specified on the command line. For example: # chronyd -q 'pool pool.ntp.org iburst' The command above would normally take about 5 seconds if the servers were well synchronised and responding to all requests. If not synchronised or responding, it would take about 10 seconds for chronyd to give up and exit with a non-zero status. A faster configuration is possible. A single server can be used instead of four servers, the number of measurements can be reduced with the maxsamples option to one (supported since chrony version 4.0), and a timeout can be specified with the -t option. The following command would take only up to about one second. # chronyd -q -t 1 'server pool.ntp.org iburst maxsamples 1' It is not recommended to run chronyd with the -q option periodically (e.g. from a cron job) as a replacement for the daemon mode, because it performs significantly worse (e.g. the clock is stepped and its frequency is not corrected). If you must run it this way and you are using a public NTP server, make sure chronyd does not always start around the first second of a minute, e.g. by adding a random sleep before the chronyd command. Public servers typically receive large bursts of requests around the first second as there is a large number of NTP clients started from cron with no delay. 2.9. Can chronyd be configured to control the clock like ntpd? It is not possible to perfectly emulate ntpd, but there are some options that can configure chronyd to behave more like ntpd if there is a reason to prefer that. In the following example the minsamples directive slows down the response to changes in the frequency and offset of the clock. The maxslewrate and corrtimeratio directives reduce the maximum frequency error due to an offset correction and the maxdrift directive reduces the maximum assumed frequency error of the clock. The makestep directive enables a step threshold and the maxchange directive enables a panic threshold. The maxclockerror directive increases the minimum dispersion rate. minsamples 32 maxslewrate 500 corrtimeratio 100 maxdrift 500 makestep 0.128 -1 maxchange 1000 1 1 maxclockerror 15 Note that increasing minsamples might cause the offsets in the tracking and sourcestats reports/logs to be significantly smaller than the actual offsets and be unsuitable for monitoring. 2.10. Can NTP server be separated from NTP client? Yes, it is possible to run multiple instances of chronyd on a computer at the same time. One can operate primarily as an NTP client to synchronise the system clock and another as a server for other computers. If they use the same filesystem, they need to be configured with different pidfiles, Unix domain command sockets, and any other file or directory specified in the configuration file. If they run in the same network namespace, they need to use different NTP and command ports, or bind the ports to different addresses or interfaces. The server instance should be started with the -x option to prevent it from adjusting the system clock and interfering with the client instance. It can be configured as a client to synchronise its NTP clock to other servers, or the client instance running on the same computer. In the latter case, the copy option (added in chrony version 4.1) can be used to assume the reference ID and stratum of the client instance, which enables detection of synchronisation loops with its own clients. On Linux, starting with chrony version 4.0, it is possible to run multiple server instances sharing a port to better utilise multiple cores of the CPU. Note that for rate limiting and client/server interleaved mode to work well it is necessary that all packets received from the same address are handled by the same server instance. An example configuration of the client instance could be pool pool.ntp.org iburst allow 127.0.0.1 port 11123 driftfile /var/lib/chrony/drift makestep 1 3 rtcsync and configuration of the first server instance could be server 127.0.0.1 port 11123 minpoll 0 maxpoll 0 copy allow cmdport 11323 bindcmdaddress /var/run/chrony/chronyd-server1.sock pidfile /var/run/chronyd-server1.pid driftfile /var/lib/chrony/drift-server1 2.11. How can chronyd be configured to minimise downtime during restarts? The dumpdir directive in chrony.conf provides chronyd a location to save a measurement history of the sources it uses when the service exits. The -r option then enables chronyd to load state from the dump files, reducing the synchronisation time after a restart. Similarly, the ntsdumpdir directive provides a location for chronyd to save NTS cookies received from the server to avoid making a NTS-KE request when chronyd is started. When operating as an NTS server, chronyd also saves cookies keys to this directory to allow clients to continue to use the old keys after a server restart for a more seamless experience. On Linux systems, systemd socket activation provides a mechanism to reuse server sockets across chronyd restarts, so that client requests will be buffered until the service is again able to handle the requests. This allows for zero-downtime service restarts, simplified dependency logic at boot, and on-demand service spawning (for instance, for separated server chronyd instances run with the -x flag). Socket activation is supported since chrony version 4.5. The service manager (systemd) creates sockets and passes file descriptors to them to the process via the LISTEN_FDS environment variable. Before opening new sockets, chronyd first checks for and attempts to reuse matching sockets passed from the service manager. For instance, if an IPv4 datagram socket bound on bindaddress and port is available, it will be used by the NTP server to accept incoming IPv4 requests. An example systemd socket unit is below, where chronyd is configured with bindaddress 0.0.0.0, bindaddress ::, port 123, and ntsport 4460. [Unit] Description=chronyd server sockets [Socket] Service=chronyd.service # IPv4 NTP server ListenDatagram=0.0.0.0:123 # IPv6 NTP server ListenDatagram=[::]:123 # IPv4 NTS-KE server ListenStream=0.0.0.0:4460 # IPv6 NTS-KE server ListenStream=[::]:4460 BindIPv6Only=ipv6-only [Install] WantedBy=sockets.target 2.12. Should be a leap smear enabled on NTP server? With the smoothtime and leapsecmode directives it is possible to enable a server leap smear in order to hide leap seconds from clients and force them to follow a slow server's adjustment instead. This feature should be used only in local networks and only when necessary, e.g. when the clients cannot be configured to handle the leap seconds as needed, or their number is so large that configuring them all would be impractical. The clients should use only one leap-smearing server, or multiple identically configured leap-smearing servers. Note that some clients can get leap seconds from other sources (e.g. with the leapsectz directive in chrony) and they will not work correctly with a leap smearing server. 2.13. How should chronyd be configured with gpsd? A GPS or other GNSS receiver can be used as a reference clock with gpsd. It can work as one or two separate time sources for each connected receiver. The first time source is based on timestamping of messages sent by the receiver. Typically, it is accurate to milliseconds. The other source is much more accurate. It is timestamping a pulse-per-second (PPS) signal, usually connected to a serial port (e.g. DCD pin) or GPIO pin. If the PPS signal is connected to the serial port which is receiving messages from the GPS/GNSS receiver, gpsd should detect and use it automatically. If it is connected to a GPIO pin, or another serial port, the PPS device needs to be specified on the command line as an additional data source. On Linux, the ldattach utility can be used to create a PPS device for a serial device. The PPS-based time source provided by gpsd is available as a SHM 1 refclock, or other odd number if gpsd is configured with multiple receivers, and also as SOCK /var/run/chrony.DEV.sock where DEV is the name of the serial device (e.g. ttyS0). The message-based time source is available as a SHM 0 refclock (or other even number) and since gpsd version 3.25 also as SOCK /var/run/chrony.clk.DEV.sock where DEV is the name of the serial device. The SOCK refclocks should be preferred over SHM for better security (the shared memory segment needs to be created by chronyd or gpsd with an expected owner and permissions before an untrusted application or user has a chance to create its own in order to feed chronyd with false measurements). gpsd needs to be started after chronyd in order to connect to the socket. With chronyd and gpsd both supporting PPS, there are two different recommended configurations: # First option refclock SOCK /var/run/chrony.ttyS0.sock refid GPS # Second option refclock PPS /dev/pps0 lock NMEA refid GPS refclock SOCK /var/run/chrony.clk.ttyS0.sock offset 0.5 delay 0.1 refid NMEA noselect They both have some advantages: o SOCK can be more accurate than PPS if gpsd corrects for the sawtooth error provided by the receiver in serial data o PPS can be used with higher PPS rates (specified by the rate option), but it requires a second refclock or another time source to pair pulses with seconds, and the SOCK offset needs to be specified correctly to compensate for the message delay, while gpsd can apply HW-specific information If the PPS signal is not available, or cannot be used for some reason, the only option is the message-based timing refclock SOCK /var/run/chrony.clk.ttyS0.sock offset 0.5 delay 0.1 refid GPS or the SHM equivalent if using gpsd version before 3.25 refclock SHM 0 offset 0.5 delay 0.1 refid GPS 2.14. Does chrony support PTP? No, the Precision Time Protocol (PTP) is not supported as a protocol for synchronisation of clocks and there are no plans to support it. It is a complex protocol, which shares some issues with the NTP broadcast mode. One of the main differences between NTP and PTP is that PTP was designed to be easily supported in hardware (e.g. network switches and routers) in order to make more stable and accurate measurements. PTP relies on the hardware support. NTP does not rely on any support in the hardware, but if it had the same support as PTP, it could perform equally well. On Linux, chrony supports hardware clocks that some NICs have for PTP. They are called PTP hardware clocks (PHC). They can be used as reference clocks (specified by the refclock directive) and for hardware timestamping of NTP packets (enabled by the hwtimestamp directive) if the NIC can timestamp other packets than PTP, which is usually the case at least for transmitted packets. The ethtool -T command can be used to verify the timestamping support. As an experimental feature added in version 4.2, chrony can use PTP as a transport for NTP messages (NTP over PTP) to enable hardware timestamping on hardware which can timestamp PTP packets only. It can be enabled by the ptpport directive. Since version 4.5, chrony can also apply corrections provided by PTP one-step end-to-end transparent clocks to reach the accuracy of ordinary PTP clocks. The application of PTP corrections can be enabled by the extfield F324 option. 2.15. How can I avoid using wrong PHC refclock? If your system has multiple PHC devices, normally named by udev as /dev/ptp0, / dev/ptp1, and so on, their order can change randomly across reboots depending on the order of initialisation of their drivers. If a PHC refclock is specified by this name, chronyd could be using a wrong refclock after reboot. To prevent that, you can configure udev to create a stable symlink for chronyd with a rule like this (e.g. written to /etc/udev/rules.d/80-phc.rules): KERNEL=="ptp[0-9]*", DEVPATH=="/devices/pci0000:00/0000:00:01.2/0000:02:00.0/ptp/*", SYMLINK+="ptp-i350-1" You can get the full DEVPATH of an existing PHC device with the udevadm info command. You will need to execute the udevadm trigger command, or reboot the system, for these changes to take effect. 2.16. Why are client log records dropped before reaching clientloglimit? The number of dropped client log records reported by the serverstats command can be increasing before the number of clients reported by the clients command reaches the maximum value corresponding to the memory limit set by the clientloglimit directive. This is due to the design of the data structure keeping the client records. It is a hash table which can store only up to 16 colliding addresses per slot. If a slot has more collisions and the table already has the maximum size, the oldest record will be dropped and replaced by the new client. Note that the size of the table is always a power of two and it can only grow. The limit set by the clientloglimit directive takes into account that two copies of the table exist when it is being resized. This means the actual memory usage reported by top and other utilities can be significantly smaller than the limit even when the maximum number of records is used. The absolute maximum number of client records kept at the same time is 16777216. 2.17. What happened to the commandkey and generatecommandkey directives? They were removed in version 2.2. Authentication is no longer supported in the command protocol. Commands that required authentication are now allowed only through a Unix domain socket, which is accessible only by the root and chrony users. If you need to configure chronyd remotely or locally without the root password, please consider using ssh and/or sudo to run chronyc under the root or chrony user on the host where chronyd is running. 3. Computer is not synchronising This is the most common problem. There are a number of reasons, see the following questions. 3.1. Behind a firewall? Check the Reach value printed by the chronyc's sources command. If it is zero, it means chronyd did not get any valid responses from the NTP server you are trying to use. If there is a firewall between you and the server, the requests sent to the UDP port 123 of the server or responses sent back from the port might be blocked. Try using a tool like wireshark or tcpdump to see if you are getting any responses from the server. When chronyd is receiving responses from the servers, the output of the sources command issued few minutes after chronyd start might look like this: MS Name/IP address Stratum Poll Reach LastRx Last sample =============================================================================== ^* ntp1.example.net 2 6 377 34 +484us[ -157us] +/- 30ms ^- ntp2.example.net 2 6 377 34 +33ms[ +32ms] +/- 47ms ^+ ntp3.example.net 3 6 377 35 -1397us[-2033us] +/- 60ms 3.2. Are NTP servers specified with the offline option? Check that the chronyc's online and offline commands are used appropriately (e.g. in the system networking scripts). The activity command prints the number of sources that are currently online and offline. For example: 200 OK 3 sources online 0 sources offline 0 sources doing burst (return to online) 0 sources doing burst (return to offline) 0 sources with unknown address 3.3. Is name resolution working correctly? NTP servers specified by their hostname (instead of an IP address) have to have their names resolved before chronyd can send any requests to them. If the activity command prints a non-zero number of sources with unknown address, there is an issue with the resolution. Typically, a DNS server is specified in /etc/resolv.conf. Make sure it is working correctly. Since chrony version 4.0, you can run chronyc -N sources -a command to print all sources, even those that do not have a known address yet, with their names as they were specified in the configuration. This can be useful to verify that the names specified in the configuration are used as expected. 3.4. Is chronyd allowed to step the system clock? By default, chronyd adjusts the clock gradually by slowing it down or speeding it up. If the clock is too far from the true time, it will take a long time to correct the error. The System time value printed by the chronyc's tracking command is the remaining correction that needs to be applied to the system clock. The makestep directive can be used to allow chronyd to step the clock. For example, if chrony.conf had makestep 1 3 the clock would be stepped in the first three updates if its offset was larger than one second. Normally, it is recommended to allow the step only in the first few updates, but in some cases (e.g. a computer without an RTC or virtual machine which can be suspended and resumed with an incorrect time) it might be necessary to allow the step on any clock update. The example above would change to makestep 1 -1 3.5. Using NTS? The Network Time Security (NTS) mechanism uses Transport Layer Security (TLS) to establish the keys needed for authentication of NTP packets. Run the authdata command to check whether the key establishment was successful: # chronyc -N authdata Name/IP address Mode KeyID Type KLen Last Atmp NAK Cook CLen ========================================================================= ntp1.example.net NTS 1 15 256 33m 0 0 8 100 ntp2.example.net NTS 1 15 256 33m 0 0 8 100 ntp3.example.net NTS 1 15 256 33m 0 0 8 100 The KeyID, Type, and KLen columns should have non-zero values. If they are zero, check the system log for error messages from chronyd. One possible cause of failure is a firewall blocking the client's connection to the server's TCP port 4460. Another possible cause of failure is a certificate that is failing to verify because the client's clock is wrong. This is a chicken-and-egg problem with NTS. You might need to manually correct the date, or temporarily disable NTS, in order to get NTS working. If your computer has an RTC and it is backed up by a good battery, this operation should be needed only once, assuming the RTC will be set periodically with the rtcsync directive, or compensated with the rtcfile directive and the -s option. If the computer does not have an RTC or battery, you can use the -s option without rtcfile directive to restore time of the last shutdown or reboot from the drift file. The clock will start behind the true time, but if the computer was not shut down for too long and the server's certificate was not renewed too close to its expiration, it should be sufficient for the time checks to succeed. If you run your own server, you can use a self-signed certificate covering all dates where the client can start (e.g. years 1970-2100). The certificate needs to be installed on the client and specified with the ntstrustedcerts directive. The server can have multiple names and certificates. To avoid trusting a certificate for too long, a new certificate can be added to the server periodically (e.g. once per year) and the client can have the server name and trusted certificate updated automatically (e.g. using a package repository, or a cron script downloading the files directly from the server over HTTPS). A client that was shut down for years will still be able to synchronise its clock and perform the update as long as the server keeps the old certificate. As a last resort, you can disable the time checks by the nocerttimecheck directive. This has some important security implications. To reduce the security risk, you can use the nosystemcert and ntstrustedcerts directives to disable the system's default trusted certificate authorities and trust only a minimal set of selected authorities needed to validate the certificates of used NTP servers. 3.6. Using a Windows NTP server? A common issue with Windows NTP servers is that they report a very large root dispersion (e.g. three seconds or more), which causes chronyd to ignore the server for being too inaccurate. The sources command might show a valid measurement, but the server is not selected for synchronisation. You can check the root dispersion of the server with the chronyc's ntpdata command. The maxdistance value needs to be increased in chrony.conf to enable synchronisation to such a server. For example: maxdistance 16.0 3.7. An unreachable source is selected? When chronyd is configured with multiple time sources, it tries to select the most accurate and stable sources for synchronisation of the system clock. They are marked with the * or + symbol in the report printed by the sources command. When the best source (marked with the * symbol) becomes unreachable (e.g. NTP server stops responding), chronyd will not immediately switch to the second best source in an attempt to minimise the error of the clock. It will let the clock run free for as long as its estimated error (in terms of root distance) based on previous measurements is smaller than the estimated error of the second source, and there is still an interval which contains some measurements from both sources. If the first source was significantly better than the second source, it can take many hours before the second source is selected, depending on its polling interval. You can force a faster reselection by increasing the clock error rate (maxclockerror directive), shortening the polling interval (maxpoll option), or reducing the number of samples (maxsamples option). 3.8. Does selected source drop new measurements? chronyd can drop a large number of successive NTP measurements if they are not passing some of the NTP tests. The sources command can report for a selected source the fully-reachable value of 377 in the Reach column and at the same time a LastRx value that is much larger than the current polling interval. If the source is online, this indicates that a number of measurements was dropped. You can use the ntpdata command to check the NTP tests for the last measurement. Usually, it is the test C which fails. This can be an issue when there is a long-lasting increase in the measured delay, e.g. due to a routing change in the network. Unfortunately, chronyd does not know for how long it should wait for the delay to come back to the original values, or whether it is a permanent increase and it should start from scratch. The test C is an adaptive filter. It can take many hours before it accepts a measurement with the larger delay, and even much longer before it drops all measurements with smaller delay, which determine an expected delay used by the test. You can use the reset sources command to drop all measurements immediately (available in chrony 4.0 and later). If this issue happens frequently, you can effectively disable the test by setting the maxdelaydevratio option to a very large value (e.g. 1000000), or speed up the recovery by increasing the clock error rate with the maxclockerror directive. 3.9. Using a PPS reference clock? A pulse-per-second (PPS) reference clock requires a non-PPS time source to determine which second of UTC corresponds to each pulse. If it is another reference clock specified with the lock option in the refclock directive, the offset between the two reference clocks must be smaller than 0.4 seconds (0.2 seconds with chrony versions before 4.1) in order for the PPS reference clock to work. With NMEA reference clocks it is common to have a larger offset. It needs to be corrected with the offset option. One approach to find out a good value of the offset option is to configure the reference clocks with the noselect option and compare them to an NTP server. For example, if the sourcestats command showed Name/IP Address NP NR Span Frequency Freq Skew Offset Std Dev ============================================================================== PPS0 0 0 0 +0.000 2000.000 +0ns 4000ms NMEA 58 30 231 -96.494 38.406 +504ms 6080us ntp1.example.net 7 3 200 -2.991 16.141 -107us 492us the offset of the NMEA source would need to be increased by about 0.504 seconds. It does not have to be very accurate. As long as the offset of the NMEA reference clock stays below the limit, the PPS reference clock should be able to determine the seconds corresponding to the pulses and allow the samples to be used for synchronisation. 4. Issues with chronyc 4.1. I keep getting the error 506 Cannot talk to daemon When accessing chronyd remotely, make sure that the chrony.conf file (on the computer where chronyd is running) has a cmdallow entry for the computer you are running chronyc on and an appropriate bindcmdaddress directive. This is not necessary for localhost. Perhaps chronyd is not running. Try using the ps command (e.g. on Linux, ps -auxw) to see if it is running. Or try netstat -a and see if the UDP port 323 is listening. If chronyd is not running, you might have a problem with the way you are trying to start it (e.g. at boot time). Perhaps you have a firewall set up in a way that blocks packets on the UDP port 323. You need to amend the firewall configuration in this case. 4.2. I keep getting the error 501 Not authorised This error indicates that chronyc sent the command to chronyd using a UDP socket instead of the Unix domain socket (e.g. /var/run/chrony/chronyd.sock), which is required for some commands. For security reasons, only the root and chrony users are allowed to access the socket. It is also possible that the socket does not exist. chronyd will not create the socket if the directory has a wrong owner or permissions. In this case there should be an error message from chronyd in the system log. 4.3. What is the reference ID reported by the tracking command? The reference ID is a 32-bit value used in NTP to prevent synchronisation loops. In chrony versions before 3.0 it was printed in the quad-dotted notation, even if the reference source did not actually have an IPv4 address. For IPv4 addresses, the reference ID is equal to the address, but for IPv6 addresses it is the first 32 bits of the MD5 sum of the address. For reference clocks, the reference ID is the value specified with the refid option in the refclock directive. Since version 3.0, the reference ID is printed as a hexadecimal number to avoid confusion with IPv4 addresses. If you need to get the IP address of the current reference source, use the -n option to disable resolving of IP addresses and read the second field (printed in parentheses) on the Reference ID line. 4.4. Is the chronyc / chronyd protocol documented anywhere? Only by the source code. See cmdmon.c (chronyd side) and client.c (chronyc side). Note that this protocol is not compatible with the mode 6 or mode 7 protocol supported by ntpd, i.e. the ntpq or ntpdc utility cannot be used to monitor chronyd, and chronyc cannot be used to monitor ntpd. 5. Real-time clock issues 5.1. What is the real-time clock (RTC)? This is the clock which keeps the time even when your computer is turned off. It is used to initialise the system clock on boot. It normally does not drift more than few seconds per day. There are two approaches how chronyd can work with it. One is to use the rtcsync directive, which tells chronyd to enable a kernel mode which sets the RTC from the system clock every 11 minutes. chronyd itself will not touch the RTC. If the computer is not turned off for a long time, the RTC should still be close to the true time when the system clock will be initialised from it on the next boot. The other option is to use the rtcfile directive, which tells chronyd to monitor the rate at which the RTC gains or loses time. When chronyd is started with the -s option on the next boot, it will set the system time from the RTC and also compensate for the drift it has measured previously. The rtcautotrim directive can be used to keep the RTC close to the true time, but it is not strictly necessary if its only purpose is to set the system clock when chronyd is started on boot. See the documentation for details. 5.2. Does hwclock have to be disabled? The hwclock program is run by default in the boot and/or shutdown scripts in some Linux installations. With the kernel RTC synchronisation (rtcsync directive), the RTC will be set also every 11 minutes as long as the system clock is synchronised. If you want to use chronyd's RTC monitoring (rtcfile directive), it is important to disable hwclock in the shutdown procedure. If you do not do that, it will overwrite the RTC with a new value, unknown to chronyd. At the next reboot, chronyd started with the -s option will compensate this (wrong) time with its estimate of how far the RTC has drifted whilst the power was off, giving a meaningless initial system time. There is no need to remove hwclock from the boot process, as long as chronyd is started after it has run. 5.3. I just keep getting the 513 RTC driver not running message For the real-time clock support to work, you need the following three things o an RTC in your computer o a Linux kernel with enabled RTC support o an rtcfile directive in your chrony.conf file 5.4. I get Could not open /dev/rtc, Device or resource busy in my syslog file Some other program running on the system might be using the device. 5.5. When I start chronyd, the log says Could not enable RTC interrupt : Invalid argument (or it may say disable) Your real-time clock hardware might not support the required ioctl requests: o RTC_UIE_ON o RTC_UIE_OFF A possible solution could be to build the Linux kernel with support for software emulation instead; try enabling the following configuration option when building the Linux kernel: o CONFIG_RTC_INTF_DEV_UIE_EMUL 5.6. What if my computer does not have an RTC or backup battery? In this case you can still use the -s option to set the system clock to the last modification time of the drift file, which should correspond to the system time when chronyd was previously stopped. The initial system time will be increasing across reboots and applications started after chronyd will not observe backward steps. 6. NTP-specific issues 6.1. Can chronyd be driven from broadcast/multicast NTP servers? No, the broadcast/multicast client mode is not supported and there is currently no plan to implement it. While this mode can simplify configuration of clients in large networks, it is inherently less accurate and less secure (even with authentication) than the ordinary client/server mode. When configuring a large number of clients in a network, it is recommended to use the pool directive with a DNS name which resolves to addresses of multiple NTP servers. The clients will automatically replace the servers when they become unreachable, or otherwise unsuitable for synchronisation, with new servers from the pool. Even with very modest hardware, an NTP server can serve time to hundreds of thousands of clients using the ordinary client/server mode. 6.2. Can chronyd transmit broadcast NTP packets? Yes, the broadcast directive can be used to enable the broadcast server mode to serve time to clients in the network which support the broadcast client mode (it is not supported in chronyd). Note that this mode should generally be avoided. See the previous question. 6.3. Can chronyd keep the system clock a fixed offset away from real time? Yes. Starting from version 3.0, an offset can be specified by the offset option for all time sources in the chrony.conf file. 6.4. What happens if the network connection is dropped without using chronyc's offline command first? chronyd will keep trying to access the sources that it thinks are online, and it will take longer before new measurements are actually made and the clock is corrected when the network is connected again. If the sources were set to offline, chronyd would make new measurements immediately after issuing the online command. Unless the network connection lasts only few minutes (less than the maximum polling interval), the delay is usually not a problem, and it might be acceptable to keep all sources online all the time. 6.5. Why is an offset measured between two computers synchronised to each another? When two computers are synchronised to each other using the client/server or symmetric NTP mode, there is an expectation that NTP measurements between the two computers made on both ends show an average offset close to zero. With chronyd that can be expected only when the interleaved mode is enabled by the xleave option. Otherwise, chronyd will use different transmit timestamps (e.g. daemon timestamp vs kernel timestamp) for serving time and synchronisation of its own clock, which will cause the other computer to measure a significant offset. 7. Operation 7.1. What clocks does chronyd use? There are several different clocks used by chronyd: o System clock: software clock maintained by the kernel. It is the main clock used by applications running on the computer. It is synchronised by chronyd to its NTP clock, unless started with the -x option. o NTP clock: software clock (virtual) based on the system clock and internal to chronyd. It keeps the best estimate of the true time according to the configured time sources, which is served to NTP clients unless time smoothing is enabled by the smoothtime directive. The System time value in the tracking report is the current offset between the system and NTP clock. o Real-time clock (RTC): hardware clock keeping time even when the computer is turned off. It is used by the kernel to initialise the system clock on boot and also by chronyd to compensate for its measured drift if configured with the rtcfile directive and started with the -s option. The clock can be kept accurate only by stepping enabled by the rtcsync or rtcautotrim directive. o Reference clock: hardware clock used as a time source. It is specified by the refclock directive. o NIC clock (also known as PTP hardware clock): hardware clock timestamping packets received and transmitted by a network device specified by the hwtimestamp directive. The clock is expected to be running free. It is not synchronised by chronyd. Its offset is tracked relative to the NTP clock in order to convert the hardware timestamps. 8. Operating systems 8.1. Does chrony support Windows? No. The chronyc program (the command-line client used for configuring chronyd while it is running) has been successfully built and run under Cygwin in the past. chronyd is not portable, because part of it is very system-dependent. It needs adapting to work with Windows' equivalent of the adjtimex() call, and it needs to be made to work as a service. 8.2. Are there any plans to support Windows? We have no plans to do this. Anyone is welcome to pick this work up and contribute it back to the project. Last updated 2023-12-05 14:22:10 +0100 usr/share/doc/openssl/FAQ000064400000000124152530416050011237 0ustar00The FAQ is now maintained on the web: https://www.openssl.org/docs/faq.html usr/share/doc/bash/FAQ000064400000303176152530767660010526 0ustar00This is the Bash FAQ, version 4.14, for Bash version 4.4. [THIS FAQ IS NO LONGER MAINTAINED] This document contains a set of frequently-asked questions concerning Bash, the GNU Bourne-Again Shell. Bash is a freely-available command interpreter with advanced features for both interactive use and shell programming. Another good source of basic information about shells is the collection of FAQ articles periodically posted to comp.unix.shell. Questions and comments concerning this document should be sent to chet.ramey@case.edu. This document is available for anonymous FTP with the URL ftp://ftp.cwru.edu/pub/bash/FAQ The Bash home page is http://cnswww.cns.cwru.edu/~chet/bash/bashtop.html ---------- Contents: Section A: The Basics A1) What is it? A2) What's the latest version? A3) Where can I get it? A4) On what machines will bash run? A5) Will bash run on operating systems other than Unix? A6) How can I build bash with gcc? A7) How can I make bash my login shell? A8) I just changed my login shell to bash, and now I can't FTP into my machine. Why not? A9) What's the `POSIX Shell and Utilities standard'? A10) What is the bash `posix mode'? Section B: The latest version B1) What's new in version 4.3? B2) Are there any user-visible incompatibilities between bash-4.3 and previous bash versions? Section C: Differences from other Unix shells C1) How does bash differ from sh, the Bourne shell? C2) How does bash differ from the Korn shell, version ksh88? C3) Which new features in ksh-93 are not in bash, and which are? Section D: Why does bash do some things differently than other Unix shells? D1) Why does bash run a different version of `command' than `which command' says it will? D2) Why doesn't bash treat brace expansions exactly like csh? D3) Why doesn't bash have csh variable modifiers? D4) How can I make my csh aliases work when I convert to bash? D5) How can I pipe standard output and standard error from one command to another, like csh does with `|&'? D6) Now that I've converted from ksh to bash, are there equivalents to ksh features like autoloaded functions and the `whence' command? Section E: Why does bash do certain things the way it does? E1) Why is the bash builtin `test' slightly different from /bin/test? E2) Why does bash sometimes say `Broken pipe'? E3) When I have terminal escape sequences in my prompt, why does bash wrap lines at the wrong column? E4) If I pipe the output of a command into `read variable', why doesn't the output show up in $variable when the read command finishes? E5) I have a bunch of shell scripts that use backslash-escaped characters in arguments to `echo'. Bash doesn't interpret these characters. Why not, and how can I make it understand them? E6) Why doesn't a while or for loop get suspended when I type ^Z? E7) What about empty for loops in Makefiles? E8) Why does the arithmetic evaluation code complain about `08'? E9) Why does the pattern matching expression [A-Z]* match files beginning with every letter except `z'? E10) Why does `cd //' leave $PWD as `//'? E11) If I resize my xterm while another program is running, why doesn't bash notice the change? E12) Why don't negative offsets in substring expansion work like I expect? E13) Why does filename completion misbehave if a colon appears in the filename? E14) Why does quoting the pattern argument to the regular expression matching conditional operator (=~) cause matching to stop working? E15) Tell me more about the shell compatibility level. Section F: Things to watch out for on certain Unix versions F1) Why can't I use command line editing in my `cmdtool'? F2) I built bash on Solaris 2. Why do globbing expansions and filename completion chop off the first few characters of each filename? F3) Why does bash dump core after I interrupt username completion or `~user' tilde expansion on a machine running NIS? F4) I'm running SVR4.2. Why is the line erased every time I type `@'? F5) Why does bash report syntax errors when my C News scripts use a redirection before a subshell command? F6) Why can't I use vi-mode editing on Red Hat Linux 6.1? F7) Why do bash-2.05a and bash-2.05b fail to compile `printf.def' on HP/UX 11.x? Section G: How can I get bash to do certain common things? G1) How can I get bash to read and display eight-bit characters? G2) How do I write a function `x' to replace builtin command `x', but still invoke the command from within the function? G3) How can I find the value of a shell variable whose name is the value of another shell variable? G4) How can I make the bash `time' reserved word print timing output that looks like the output from my system's /usr/bin/time? G5) How do I get the current directory into my prompt? G6) How can I rename "*.foo" to "*.bar"? G7) How can I translate a filename from uppercase to lowercase? G8) How can I write a filename expansion (globbing) pattern that will match all files in the current directory except "." and ".."? Section H: Where do I go from here? H1) How do I report bugs in bash, and where should I look for fixes and advice? H2) What kind of bash documentation is there? H3) What's coming in future versions? H4) What's on the bash `wish list'? H5) When will the next release appear? ---------- Section A: The Basics A1) What is it? Bash is a Unix command interpreter (shell). It is an implementation of the Posix 1003.2 shell standard, and resembles the Korn and System V shells. Bash contains a number of enhancements over those shells, both for interactive use and shell programming. Features geared toward interactive use include command line editing, command history, job control, aliases, and prompt expansion. Programming features include additional variable expansions, shell arithmetic, and a number of variables and options to control shell behavior. Bash was originally written by Brian Fox of the Free Software Foundation. The current developer and maintainer is Chet Ramey of Case Western Reserve University. A2) What's the latest version? The latest version is 4.3, first made available on 26 February, 2014. A3) Where can I get it? Bash is the GNU project's shell, and so is available from the master GNU archive site, ftp.gnu.org, and its mirrors. The latest version is also available for FTP from ftp.cwru.edu. The following URLs tell how to get version 4.3: ftp://ftp.gnu.org/pub/gnu/bash/bash-4.3.tar.gz ftp://ftp.cwru.edu/pub/bash/bash-4.3.tar.gz Formatted versions of the documentation are available with the URLs: ftp://ftp.gnu.org/pub/gnu/bash/bash-doc-4.3.tar.gz ftp://ftp.cwru.edu/pub/bash/bash-doc-4.3.tar.gz Any patches for the current version are available with the URL: ftp://ftp.cwru.edu/pub/bash/bash-4.3-patches/ A4) On what machines will bash run? Bash has been ported to nearly every version of Unix. All you should have to do to build it on a machine for which a port exists is to type `configure' and then `make'. The build process will attempt to discover the version of Unix you have and tailor itself accordingly, using a script created by GNU autoconf. More information appears in the file `INSTALL' in the distribution. The Bash web page (http://cnswww.cns.cwru.edu/~chet/bash/bashtop.html) explains how to obtain binary versions of bash for most of the major commercial Unix systems. A5) Will bash run on operating systems other than Unix? Configuration specifics for Unix-like systems such as QNX and LynxOS are included in the distribution. Bash-2.05 and later versions should compile and run on Minix 2.0 (patches were contributed), but I don't believe anyone has built bash-2.x on earlier Minix versions yet. Bash has been ported to versions of Windows implementing the Win32 programming interface. This includes Windows 95 and Windows NT. The port was done by Cygnus Solutions (now part of Red Hat) as part of their CYGWIN project. For more information about the project, see http://www.cygwin.com/. Cygnus originally ported bash-1.14.7, and that port was part of their early GNU-Win32 (the original name) releases. Cygnus has also done ports of bash-3.2 and bash-4.0 to the CYGWIN environment, and both are available as part of their current release. Bash-2.05b and later versions should require no local Cygnus changes to build and run under CYGWIN. DJ Delorie has a port of bash-2.x which runs under MS-DOS, as part of the DJGPP project. For more information on the project, see http://www.delorie.com/djgpp/ I have been told that the original DJGPP port was done by Daisuke Aoyama. Mark Elbrecht has sent me notice that bash-2.04 is available for DJGPP V2. The files are available as: ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2gnu/bsh204b.zip binary ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2gnu/bsh204d.zip documentation ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2gnu/bsh204s.zip source Mark began to work with bash-2.05, but I don't know the current status. Bash-3.0 compiles and runs with no modifications under Microsoft's Services for Unix (SFU), once known as Interix. I do not anticipate any problems with building bash-4.2 and later, but will gladly accept any patches that are needed. A6) How can I build bash with gcc? Bash configures to use gcc by default if it is available. Read the file INSTALL in the distribution for more information. A7) How can I make bash my login shell? Some machines let you use `chsh' to change your login shell. Other systems use `passwd -s' or `passwd -e'. If one of these works for you, that's all you need. Note that many systems require the full pathname to a shell to appear in /etc/shells before you can make it your login shell. For this, you may need the assistance of your friendly local system administrator. If you cannot do this, you can still use bash as your login shell, but you need to perform some tricks. The basic idea is to add a command to your login shell's startup file to replace your login shell with bash. For example, if your login shell is csh or tcsh, and you have installed bash in /usr/gnu/bin/bash, add the following line to ~/.login: if ( -f /usr/gnu/bin/bash ) exec /usr/gnu/bin/bash --login (the `--login' tells bash that it is a login shell). It's not a good idea to put this command into ~/.cshrc, because every csh you run without the `-f' option, even ones started to run csh scripts, reads that file. If you must put the command in ~/.cshrc, use something like if ( $?prompt ) exec /usr/gnu/bin/bash --login to ensure that bash is exec'd only when the csh is interactive. If your login shell is sh or ksh, you have to do two things. First, create an empty file in your home directory named `.bash_profile'. The existence of this file will prevent the exec'd bash from trying to read ~/.profile, and re-execing itself over and over again. ~/.bash_profile is the first file bash tries to read initialization commands from when it is invoked as a login shell. Next, add a line similar to the above to ~/.profile: [ -f /usr/gnu/bin/bash ] && [ -x /usr/gnu/bin/bash ] && \ exec /usr/gnu/bin/bash --login This will cause login shells to replace themselves with bash running as a login shell. Once you have this working, you can copy your initialization code from ~/.profile to ~/.bash_profile. I have received word that the recipe supplied above is insufficient for machines running CDE. CDE has a maze of twisty little startup files, all slightly different. If you cannot change your login shell in the password file to bash, you will have to (apparently) live with CDE using the shell in the password file to run its startup scripts. If you have changed your shell to bash, there is code in the CDE startup files (on Solaris, at least) that attempts to do the right thing. It is, however, often broken, and may require that you use the $BASH_ENV trick described below. `dtterm' claims to use $SHELL as the default program to start, so if you can change $SHELL in the CDE startup files, you should be able to use bash in your terminal windows. Setting DTSOURCEPROFILE in ~/.dtprofile will cause the `Xsession' program to read your login shell's startup files. You may be able to use bash for the rest of the CDE programs by setting SHELL to bash in ~/.dtprofile as well, but I have not tried this. You can use the above `exec' recipe to start bash when not logging in with CDE by testing the value of the DT variable: if [ -n "$DT" ]; then [ -f /usr/gnu/bin/bash ] && exec /usr/gnu/bin/bash --login fi If CDE starts its shells non-interactively during login, the login shell startup files (~/.profile, ~/.bash_profile) will not be sourced at login. To get around this problem, append a line similar to the following to your ~/.dtprofile: BASH_ENV=${HOME}/.bash_profile ; export BASH_ENV and add the following line to the beginning of ~/.bash_profile: unset BASH_ENV A8) I just changed my login shell to bash, and now I can't FTP into my machine. Why not? You must add the full pathname to bash to the file /etc/shells. As noted in the answer to the previous question, many systems require this before you can make bash your login shell. Most versions of ftpd use this file to prohibit `special' users such as `uucp' and `news' from using FTP. A9) What's the `POSIX Shell and Utilities standard'? POSIX is a name originally coined by Richard Stallman for a family of open system standards based on UNIX. There are a number of aspects of UNIX under consideration for standardization, from the basic system services at the system call and C library level to applications and tools to system administration and management. Each area of standardization is assigned to a working group in the 1003 series. The POSIX Shell and Utilities standard was originally developed by IEEE Working Group 1003.2 (POSIX.2). Today it has been merged with the original 1003.1 Working Group and is maintained by the Austin Group (a joint working group of the IEEE, The Open Group and ISO/IEC SC22/WG15). Today the Shell and Utilities are a volume within the set of documents that make up IEEE Std 1003.1-2001, and thus now the former POSIX.2 (from 1992) is now part of the current POSIX.1 standard (POSIX 1003.1-2001). The Shell and Utilities volume concentrates on the command interpreter interface and utility programs commonly executed from the command line or by other programs. The standard is freely available on the web at http://www.UNIX-systems.org/version3/ . Work continues at the Austin Group on maintenance issues; see http://www.opengroup.org/austin/ to join the discussions. Bash is concerned with the aspects of the shell's behavior defined by the POSIX Shell and Utilities volume. The shell command language has of course been standardized, including the basic flow control and program execution constructs, I/O redirection and pipelining, argument handling, variable expansion, and quoting. The `special' builtins, which must be implemented as part of the shell to provide the desired functionality, are specified as being part of the shell; examples of these are `eval' and `export'. Other utilities appear in the sections of POSIX not devoted to the shell which are commonly (and in some cases must be) implemented as builtin commands, such as `read' and `test'. POSIX also specifies aspects of the shell's interactive behavior as part of the UPE, including job control and command line editing. Only vi-style line editing commands have been standardized; emacs editing commands were left out due to objections. The latest version of the POSIX Shell and Utilities standard is available (now updated to the 2004 Edition) as part of the Single UNIX Specification Version 3 at http://www.UNIX-systems.org/version3/ A10) What is the bash `posix mode'? Although bash is an implementation of the POSIX shell specification, there are areas where the bash default behavior differs from that spec. The bash `posix mode' changes the bash behavior in these areas so that it obeys the spec more closely. Posix mode is entered by starting bash with the --posix or '-o posix' option or executing `set -o posix' after bash is running. The specific aspects of bash which change when posix mode is active are listed in the file POSIX in the bash distribution. They are also listed in a section in the Bash Reference Manual (from which that file is generated). Section B: The latest version B1) What's new in version 4.3? Bash-4.3 is the third revision to the fourth major release of bash. Bash-4.3 contains the following new features (see the manual page for complete descriptions and the CHANGES and NEWS files in the bash-4.3 distribution): o The `helptopic' completion action now maps to all the help topics, not just the shell builtins. o The `help' builtin no longer does prefix substring matching first, so `help read' does not match `readonly', but will do it if exact string matching fails. o The shell can be compiled to not display a message about processes that terminate due to SIGTERM. o Non-interactive shells now react to the setting of checkwinsize and set LINES and COLUMNS after a foreground job exits. o There is a new shell option, `globasciiranges', which, when set to on, forces globbing range comparisons to use character ordering as if they were run in the C locale. o There is a new shell option, `direxpand', which makes filename completion expand variables in directory names in the way bash-4.1 did. o In Posix mode, the `command' builtin does not change whether or not a builtin it shadows is treated as an assignment builtin. o The `return' and `exit' builtins accept negative exit status arguments. o The word completion code checks whether or not a filename containing a shell variable expands to a directory name and appends `/' to the word as appropriate. The same code expands shell variables in command names when performing command completion. o In Posix mode, it is now an error to attempt to define a shell function with the same name as a Posix special builtin. o When compiled for strict Posix conformance, history expansion is disabled by default. o The history expansion character (!) does not cause history expansion when followed by the closing quote in a double-quoted string. o `complete' and its siblings compgen/compopt now takes a new `-o noquote' option to inhibit quoting of the completions. o Setting HISTSIZE to a value less than zero causes the history list to be unlimited (setting it 0 zero disables the history list). o Setting HISTFILESIZE to a value less than zero causes the history file size to be unlimited (setting it to 0 causes the history file to be truncated to zero size). o The `read' builtin now skips NUL bytes in the input. o There is a new `bind -X' option to print all key sequences bound to Unix commands. o When in Posix mode, `read' is interruptible by a trapped signal. After running the trap handler, read returns 128+signal and throws away any partially-read input. o The command completion code skips whitespace and assignment statements before looking for the command name word to be completed. o The build process has a new mechanism for constructing separate help files that better reflects the current set of compilation options. o The -nt and -ot options to test now work with files with nanosecond timestamp resolution. o The shell saves the command history in any shell for which history is enabled and HISTFILE is set, not just interactive shells. o The shell has `nameref' variables and new -n(/+n) options to declare and unset to use them, and a `test -R' option to test for them. o The shell now allows assigning, referencing, and unsetting elements of indexed arrays using negative subscripts (a[-1]=2, echo ${a[-1]}) which count back from the last element of the array. o The {x} operators to the [[ conditional command now do string comparison according to the current locale. o Programmable completion now uses the completion for `b' instead of `a' when completion is attempted on a line like: a $(b c. o Force extglob on temporarily when parsing the pattern argument to the == and != operators to the [[ command, for compatibility. o Changed the behavior of interrupting the wait builtin when a SIGCHLD is received and a trap on SIGCHLD is set to be Posix-mode only. o The read builtin has a new `-N nchars' option, which reads exactly NCHARS characters, ignoring delimiters like newline. o The mapfile/readarray builtin no longer stores the commands it invokes via callbacks in the history list. o There is a new `compat40' shopt option. o The < and > operators to [[ do string comparisons using the current locale only if the compatibility level is greater than 40 (set to 41 by default). o New bindable readline function: menu-complete-backward. o In the readline vi-mode insertion keymap, C-n is now bound to menu-complete by default, and C-p to menu-complete-backward. o When in readline vi command mode, repeatedly hitting ESC now does nothing, even when ESC introduces a bound key sequence. This is closer to how historical vi behaves. o New bindable readline function: skip-csi-sequence. Can be used as a default to consume key sequences generated by keys like Home and End without having to bind all keys. o New bindable readline variable: skip-completed-text, active when completing in the middle of a word. If enabled, it means that characters in the completion that match characters in the remainder of the word are "skipped" rather than inserted into the line. o The pre-readline-6.0 version of menu completion is available as "old-menu-complete" for users who do not like the readline-6.0 version. o New bindable readline variable: echo-control-characters. If enabled, and the tty ECHOCTL bit is set, controls the echoing of characters corresponding to keyboard-generated signals. o New bindable readline variable: enable-meta-key. Controls whether or not readline sends the smm/rmm sequences if the terminal indicates it has a meta key that enables eight-bit characters. Bash-4.0 contained the following new features: o When using substring expansion on the positional parameters, a starting index of 0 now causes $0 to be prefixed to the list. o There is a new variable, $BASHPID, which always returns the process id of the current shell. o There is a new `autocd' option that, when enabled, causes bash to attempt to `cd' to a directory name that is supplied as the first word of a simple command. o There is a new `checkjobs' option that causes the shell to check for and report any running or stopped jobs at exit. o The programmable completion code exports a new COMP_TYPE variable, set to a character describing the type of completion being attempted. o The programmable completion code exports a new COMP_KEY variable, set to the character that caused the completion to be invoked (e.g., TAB). o The programmable completion code now uses the same set of characters as readline when breaking the command line into a list of words. o The block multiplier for the ulimit -c and -f options is now 512 when in Posix mode, as Posix specifies. o Changed the behavior of the read builtin to save any partial input received in the specified variable when the read builtin times out. This also results in variables specified as arguments to read to be set to the empty string when there is no input available. When the read builtin times out, it returns an exit status greater than 128. o The shell now has the notion of a `compatibility level', controlled by new variables settable by `shopt'. Setting this variable currently restores the bash-3.1 behavior when processing quoted strings on the rhs of the `=~' operator to the `[[' command. o The `ulimit' builtin now has new -b (socket buffer size) and -T (number of threads) options. o There is a new `compopt' builtin that allows completion functions to modify completion options for existing completions or the completion currently being executed. o The `read' builtin has a new -i option which inserts text into the reply buffer when using readline. o A new `-E' option to the complete builtin allows control of the default behavior for completion on an empty line. o There is now limited support for completing command name words containing globbing characters. o The `help' builtin now has a new -d option, to display a short description, and a -m option, to print help information in a man page-like format. o There is a new `mapfile' builtin to populate an array with lines from a given file. o If a command is not found, the shell attempts to execute a shell function named `command_not_found_handle', supplying the command words as the function arguments. o There is a new shell option: `globstar'. When enabled, the globbing code treats `**' specially -- it matches all directories (and files within them, when appropriate) recursively. o There is a new shell option: `dirspell'. When enabled, the filename completion code performs spelling correction on directory names during completion. o The `-t' option to the `read' builtin now supports fractional timeout values. o Brace expansion now allows zero-padding of expanded numeric values and will add the proper number of zeroes to make sure all values contain the same number of digits. o There is a new bash-specific bindable readline function: `dabbrev-expand'. It uses menu completion on a set of words taken from the history list. o The command assigned to a key sequence with `bind -x' now sets two new variables in the environment of the executed command: READLINE_LINE_BUFFER and READLINE_POINT. The command can change the current readline line and cursor position by modifying READLINE_LINE_BUFFER and READLINE_POINT, respectively. o There is a new >>& redirection operator, which appends the standard output and standard error to the named file. o The parser now understands `|&' as a synonym for `2>&1 |', which redirects the standard error for a command through a pipe. o The new `;&' case statement action list terminator causes execution to continue with the action associated with the next pattern in the statement rather than terminating the command. o The new `;;&' case statement action list terminator causes the shell to test the next set of patterns after completing execution of the current action, rather than terminating the command. o The shell understands a new variable: PROMPT_DIRTRIM. When set to an integer value greater than zero, prompt expansion of \w and \W will retain only that number of trailing pathname components and replace the intervening characters with `...'. o There are new case-modifying word expansions: uppercase (^[^]) and lowercase (,[,]). They can work on either the first character or array element, or globally. They accept an optional shell pattern that determines which characters to modify. There is an optionally- configured feature to include capitalization operators. o The shell provides associative array variables, with the appropriate support to create, delete, assign values to, and expand them. o The `declare' builtin now has new -l (convert value to lowercase upon assignment) and -u (convert value to uppercase upon assignment) options. There is an optionally-configurable -c option to capitalize a value at assignment. o There is a new `coproc' reserved word that specifies a coprocess: an asynchronous command run with two pipes connected to the creating shell. Coprocs can be named. The input and output file descriptors and the PID of the coprocess are available to the calling shell in variables with coproc-specific names. o A value of 0 for the -t option to `read' now returns success if there is input available to be read from the specified file descriptor. o CDPATH and GLOBIGNORE are ignored when the shell is running in privileged mode. o New bindable readline functions shell-forward-word and shell-backward-word, which move forward and backward words delimited by shell metacharacters and honor shell quoting. o New bindable readline functions shell-backward-kill-word and shell-kill-word which kill words backward and forward, but use the same word boundaries as shell-forward-word and shell-backward-word. Bash-3.2 contained the following new features: o Bash-3.2 now checks shell scripts for NUL characters rather than non-printing characters when deciding whether or not a script is a binary file. o Quoting the string argument to the [[ command's =~ (regexp) operator now forces string matching, as with the other pattern-matching operators. Bash-3.1 contained the following new features: o Bash-3.1 may now be configured and built in a mode that enforces strict POSIX compliance. o The `+=' assignment operator, which appends to the value of a string or array variable, has been implemented. o It is now possible to ignore case when matching in contexts other than filename generation using the new `nocasematch' shell option. Bash-3.0 contained the following new features: o Features to support the bash debugger have been implemented, and there is a new `extdebug' option to turn the non-default options on o HISTCONTROL is now a colon-separated list of options and has been extended with a new `erasedups' option that will result in only one copy of a command being kept in the history list o Brace expansion has been extended with a new {x..y} form, producing sequences of digits or characters o Timestamps are now kept with history entries, with an option to save and restore them from the history file; there is a new HISTTIMEFORMAT variable describing how to display the timestamps when listing history entries o The `[[' command can now perform extended regular expression (egrep-like) matching, with matched subexpressions placed in the BASH_REMATCH array variable o A new `pipefail' option causes a pipeline to return a failure status if any command in it fails o The `jobs', `kill', and `wait' builtins now accept job control notation in their arguments even if job control is not enabled o The `gettext' package and libintl have been integrated, and the shell messages may be translated into other languages Bash-2.05b introduced the following new features: o support for multibyte characters has been added to both bash and readline o the DEBUG trap is now run *before* simple commands, ((...)) commands, [[...]] conditional commands, and for ((...)) loops o the shell now performs arithmetic in the largest integer size the machine supports (intmax_t) o there is a new \D{...} prompt expansion; passes the `...' to strftime(3) and inserts the result into the expanded prompt o there is a new `here-string' redirection operator: <<< word o when displaying variables, function attributes and definitions are shown separately, allowing them to be re-used as input (attempting to re-use the old output would result in syntax errors). o `read' has a new `-u fd' option to read from a specified file descriptor o the bash debugger in examples/bashdb has been modified to work with the new DEBUG trap semantics, the command set has been made more gdb-like, and the changes to $LINENO make debugging functions work better o the expansion of $LINENO inside a shell function is only relative to the function start if the shell is interactive -- if the shell is running a script, $LINENO expands to the line number in the script. This is as POSIX-2001 requires Bash-2.05a introduced the following new features: o The `printf' builtin has undergone major work o There is a new read-only `shopt' option: login_shell, which is set by login shells and unset otherwise o New `\A' prompt string escape sequence; expanding to time in 24-hour HH:MM format o New `-A group/-g' option to complete and compgen; goes group name completion o New [+-]O invocation option to set and unset `shopt' options at startup o ksh-like `ERR' trap o `for' loops now allow empty word lists after the `in' reserved word o new `hard' and `soft' arguments for the `ulimit' builtin o Readline can be configured to place the user at the same point on the line when retrieving commands from the history list o Readline can be configured to skip `hidden' files (filenames with a leading `.' on Unix) when performing completion Bash-2.05 introduced the following new features: o This version has once again reverted to using locales and strcoll(3) when processing pattern matching bracket expressions, as POSIX requires. o Added a new `--init-file' invocation argument as a synonym for `--rcfile', per the new GNU coding standards. o The /dev/tcp and /dev/udp redirections now accept service names as well as port numbers. o `complete' and `compgen' now take a `-o value' option, which controls some of the aspects of that compspec. Valid values are: default - perform bash default completion if programmable completion produces no matches dirnames - perform directory name completion if programmable completion produces no matches filenames - tell readline that the compspec produces filenames, so it can do things like append slashes to directory names and suppress trailing spaces o A new loadable builtin, realpath, which canonicalizes and expands symlinks in pathname arguments. o When `set' is called without options, it prints function defintions in a way that allows them to be reused as input. This affects `declare' and `declare -p' as well. This only happens when the shell is not in POSIX mode, since POSIX.2 forbids this behavior. Bash-2.04 introduced the following new features: o Programmable word completion with the new `complete' and `compgen' builtins; examples are provided in examples/complete/complete-examples o `history' has a new `-d' option to delete a history entry o `bind' has a new `-x' option to bind key sequences to shell commands o The prompt expansion code has new `\j' and `\l' escape sequences o The `no_empty_cmd_completion' shell option, if enabled, inhibits command completion when TAB is typed on an empty line o `help' has a new `-s' option to print a usage synopsis o New arithmetic operators: var++, var--, ++var, --var, expr1,expr2 (comma) o New ksh93-style arithmetic for command: for ((expr1 ; expr2; expr3 )); do list; done o `read' has new options: `-t', `-n', `-d', `-s' o The redirection code handles several filenames specially: /dev/fd/N, /dev/stdin, /dev/stdout, /dev/stderr o The redirection code now recognizes /dev/tcp/HOST/PORT and /dev/udp/HOST/PORT and tries to open a TCP or UDP socket, respectively, to the specified port on the specified host o The ${!prefix*} expansion has been implemented o A new FUNCNAME variable, which expands to the name of a currently-executing function o The GROUPS variable is no longer readonly o A new shopt `xpg_echo' variable, to control the behavior of echo with respect to backslash-escape sequences at runtime o The NON_INTERACTIVE_LOGIN_SHELLS #define has returned The version of Readline released with Bash-2.04, Readline-4.1, had several new features as well: o Parentheses matching is always compiled into readline, and controllable with the new `blink-matching-paren' variable o The history-search-forward and history-search-backward functions now leave point at the end of the line when the search string is empty, like reverse-search-history, and forward-search-history o A new function for applications: rl_on_new_line_with_prompt() o New variables for applications: rl_already_prompted, and rl_gnu_readline_p Bash-2.03 had very few new features, in keeping with the convention that odd-numbered releases provide mainly bug fixes. A number of new features were added to Readline, mostly at the request of the Cygnus folks. A new shopt option, `restricted_shell', so that startup files can test whether or not the shell was started in restricted mode Filename generation is now performed on the words between ( and ) in compound array assignments (this is really a bug fix) OLDPWD is now auto-exported, as POSIX.2 requires ENV and BASH_ENV are read-only variables in a restricted shell Bash may now be linked against an already-installed Readline library, as long as the Readline library is version 4 or newer All shells begun with the `--login' option will source the login shell startup files, even if the shell is not interactive There were lots of changes to the version of the Readline library released along with Bash-2.03. For a complete list of the changes, read the file CHANGES in the Bash-2.03 distribution. Bash-2.02 contained the following new features: a new version of malloc (based on the old GNU malloc code in previous bash versions) that is more page-oriented, more conservative with memory usage, does not `orphan' large blocks when they are freed, is usable on 64-bit machines, and has allocation checking turned on unconditionally POSIX.2-style globbing character classes ([:alpha:], [:alnum:], etc.) POSIX.2-style globbing equivalence classes POSIX.2-style globbing collating symbols the ksh [[...]] extended conditional command the ksh egrep-style extended pattern matching operators a new `printf' builtin the ksh-like $(, &>, >|, <<<, [n]<&word-, [n]>&word-, >>& prompt string special char translation and variable expansion auto-export of variables in initial environment command search finds functions before builtins bash return builtin will exit a file sourced with `.' builtins: cd -/-L/-P/-@, exec -l/-c/-a, echo -e/-E, hash -d/-l/-p/-t. export -n/-f/-p/name=value, pwd -L/-P, read -e/-p/-a/-t/-n/-d/-s/-u/-i/-N, readonly -a/-f/name=value, trap -l, set +o, set -b/-m/-o option/-h/-p/-B/-C/-H/-P, unset -f/-n/-v, ulimit -i/-m/-p/-q/-u/-x, type -a/-p/-t/-f/-P, suspend -f, kill -n, test -o optname/s1 == s2/s1 < s2/s1 > s2/-nt/-ot/-ef/-O/-G/-S/-R bash reads ~/.bashrc for interactive shells, $ENV for non-interactive bash restricted shell mode is more extensive bash allows functions and variables with the same name brace expansion tilde expansion arithmetic expansion with $((...)) and `let' builtin the `[[...]]' extended conditional command process substitution aliases and alias/unalias builtins local variables in functions and `local' builtin readline and command-line editing with programmable completion command history and history/fc builtins csh-like history expansion other new bash builtins: bind, command, compgen, complete, builtin, declare/typeset, dirs, enable, fc, help, history, logout, popd, pushd, disown, shopt, printf, compopt, mapfile exported functions filename generation when using output redirection (command >a*) POSIX.2-style globbing character classes POSIX.2-style globbing equivalence classes POSIX.2-style globbing collating symbols egrep-like extended pattern matching operators case-insensitive pattern matching and globbing variable assignments preceding commands affect only that command, even for builtins and functions posix mode and strict posix conformance redirection to /dev/fd/N, /dev/stdin, /dev/stdout, /dev/stderr, /dev/tcp/host/port, /dev/udp/host/port debugger support, including `caller' builtin and new variables RETURN trap the `+=' assignment operator autocd shell option and behavior command-not-found hook with command_not_found_handle shell function globstar shell option and `**' globbing behavior |& synonym for `2>&1 |' ;& and ;;& case action list terminators case-modifying word expansions and variable attributes associative arrays coprocesses using the `coproc' reserved word and variables shell assignment of a file descriptor used in a redirection to a variable Things sh has that bash does not: uses variable SHACCT to do shell accounting includes `stop' builtin (bash can use alias stop='kill -s STOP') `newgrp' builtin turns on job control if called as `jsh' $TIMEOUT (like bash $TMOUT) `^' is a synonym for `|' new SVR4.2 sh builtins: mldmode, priv Implementation differences: redirection to/from compound commands causes sh to create a subshell bash does not allow unbalanced quotes; sh silently inserts them at EOF bash does not mess with signal 11 sh sets (euid, egid) to (uid, gid) if -p not supplied and uid < 100 bash splits only the results of expansions on IFS, using POSIX.2 field splitting rules; sh splits all words on IFS sh does not allow MAILCHECK to be unset (?) sh does not allow traps on SIGALRM or SIGCHLD bash allows multiple option arguments when invoked (e.g. -x -v); sh allows only a single option argument (`sh -x -v' attempts to open a file named `-v', and, on SunOS 4.1.4, dumps core. On Solaris 2.4 and earlier versions, sh goes into an infinite loop.) sh exits a script if any builtin fails; bash exits only if one of the POSIX.2 `special' builtins fails C2) How does bash differ from the Korn shell, version ksh88? Things bash has or uses that ksh88 does not: long invocation options [-+]O invocation option -l invocation option `!' reserved word arithmetic for command: for ((expr1 ; expr2; expr3 )); do list; done arithmetic in largest machine-supported size (intmax_t) posix mode and posix conformance command hashing tilde expansion for assignment statements that look like $PATH process substitution with named pipes if /dev/fd is not available the ${!param} indirect parameter expansion operator the ${!param*} prefix expansion operator the ${param:offset[:length]} parameter substring operator the ${param/pat[/string]} parameter pattern substitution operator variables: BASH, BASH_VERSION, BASH_VERSINFO, BASHPID, UID, EUID, SHLVL, TIMEFORMAT, HISTCMD, HOSTTYPE, OSTYPE, MACHTYPE, HISTFILESIZE, HISTIGNORE, HISTCONTROL, PROMPT_COMMAND, IGNOREEOF, FIGNORE, INPUTRC, HOSTFILE, DIRSTACK, PIPESTATUS, HOSTNAME, OPTERR, SHELLOPTS, GLOBIGNORE, GROUPS, FUNCNAME, histchars, auto_resume, PROMPT_DIRTRIM prompt expansion with backslash escapes and command substitution redirection: &> (stdout and stderr), <<<, [n]<&word-, [n]>&word-, >>& more extensive and extensible editing and programmable completion builtins: bind, builtin, command, declare, dirs, echo -e/-E, enable, exec -l/-c/-a, fc -s, export -n/-f/-p, hash, help, history, jobs -x/-r/-s, kill -s/-n/-l, local, logout, popd, pushd, read -e/-p/-a/-t/-n/-d/-s/-N, readonly -a/-n/-f/-p, set -o braceexpand/-o histexpand/-o interactive-comments/ -o notify/-o physical/-o posix/-o hashall/-o onecmd/ -h/-B/-C/-b/-H/-P, set +o, suspend, trap -l, type, typeset -a/-F/-p, ulimit -i/-q/-u/-x, umask -S, alias -p, shopt, disown, printf, complete, compgen, compopt, mapfile `!' csh-style history expansion POSIX.2-style globbing character classes POSIX.2-style globbing equivalence classes POSIX.2-style globbing collating symbols egrep-like extended pattern matching operators case-insensitive pattern matching and globbing `**' arithmetic operator to do exponentiation redirection to /dev/fd/N, /dev/stdin, /dev/stdout, /dev/stderr arrays of unlimited size TMOUT is default timeout for `read' and `select' debugger support, including the `caller' builtin RETURN trap Timestamps in history entries {x..y} brace expansion The `+=' assignment operator autocd shell option and behavior command-not-found hook with command_not_found_handle shell function globstar shell option and `**' globbing behavior |& synonym for `2>&1 |' ;& and ;;& case action list terminators case-modifying word expansions and variable attributes associative arrays coprocesses using the `coproc' reserved word and variables shell assignment of a file descriptor used in a redirection to a variable Things ksh88 has or uses that bash does not: tracked aliases (alias -t) variables: ERRNO, FPATH, EDITOR, VISUAL co-processes (bash uses different syntax) weirdly-scoped functions typeset +f to list all function names without definitions text of command history kept in a file, not memory builtins: alias -x, cd old new, newgrp, print, read -p/-s/var?prompt, set -A/-o gmacs/ -o bgnice/-o markdirs/-o trackall/-o viraw/-s, typeset -H/-L/-R/-Z/-A/-ft/-fu/-fx/-t, whence using environment to pass attributes of exported variables arithmetic evaluation done on arguments to some builtins reads .profile from $PWD when invoked as login shell Implementation differences: ksh runs last command of a pipeline in parent shell context bash has brace expansion by default (ksh88 compile-time option) bash has fixed startup file for all interactive shells; ksh reads $ENV bash has exported functions bash command search finds functions before builtins bash waits for all commands in pipeline to exit before returning status emacs-mode editing has some slightly different key bindings C3) Which new features in ksh-93 are not in bash, and which are? This list is current through ksh93v (10/08/2013) New things in ksh-93 not in bash-4.3: floating point arithmetic, variables, and constants math library functions, including user-defined math functions ${!name[sub]} name of subscript for associative array `.' is allowed in variable names to create a hierarchical namespace more extensive compound assignment syntax discipline functions KEYBD trap variables: .sh.edchar, .sh.edmode, .sh.edcol, .sh.edtext, .sh.version, .sh.name, .sh.subscript, .sh.value, .sh.match, HISTEDIT, .sh.sig, .sh.stats, .sh.siginfo, .sh.pwdfd, .sh.op_astbin, .sh.pool backreferences in pattern matching (\N) `&' operator in pattern lists for matching (match all instead of any) exit statuses between 0 and 255 FPATH and PATH mixing lexical scoping for local variables in `ksh' functions no scoping for local variables in `POSIX' functions $'' \C[.collating-element.] escape sequence -C/-I invocation options print -f (bash uses printf) and rest of print builtin options printf %(type)q, %#q `fc' has been renamed to `hist' `.' can execute shell functions getopts -a printf %B, %H, %P, %R, %Z modifiers, output base for %d, `=' flag read -n/-N differ/-v/-S set -o showme/-o multiline (bash default) set -K kill -Q/-q/-L trap -a `sleep' and `getconf' builtins (bash has loadable versions) [[ -R name ]] (checks whether or not name is a nameref) typeset -C/-S/-T/-X/-h/-s/-c/-M experimental `type' definitions (a la typedef) using typeset array expansions ${array[sub1..sub2]} and ${!array[sub1..sub2]} associative array assignments using `;' as element separator command substitution $(n<#) expands to current byte offset for fd N new '${ ' form of command substitution, executed in current shell new >;/<>;/<#pat/<##pat/<#/># redirections brace expansion printf-like formats CHLD trap triggered by SIGSTOP and SIGCONT ~{fd} expansion, which replaces fd with the corresponding path name $"string" expanded when referenced rather than when first parsed job "pools", which allow a collection of jobs to be managed as a unit New things in ksh-93 present in bash-4.3: associative arrays [n]<&word- and [n]>&word- redirections (combination dup and close) for (( expr1; expr2; expr3 )) ; do list; done - arithmetic for command ?:, ++, --, `expr1 , expr2' arithmetic operators expansions: ${!param}, ${param:offset[:len]}, ${param/pat[/str]}, ${!param*} compound array assignment negative subscripts for indexed array variables the `!' reserved word loadable builtins -- but ksh uses `builtin' while bash uses `enable' new $'...' and $"..." quoting FIGNORE (but bash uses GLOBIGNORE), HISTCMD brace expansion and set -B changes to kill builtin `command', `builtin', `disown' builtins echo -e exec -c/-a printf %T modifier read -A (bash uses read -a) read -t/-d trap -p `.' restores the positional parameters when it completes set -o notify/-C set -o pipefail set -G (-o globstar) and ** POSIX.2 `test' umask -S unalias -a command and arithmetic substitution performed on PS1, PS4, and ENV command name completion, TAB displaying possible completions ENV processed only for interactive shells The `+=' assignment operator the `;&' case statement "fallthrough" pattern list terminator csh-style history expansion and set -H negative offsets in ${param:offset:length} redirection operators preceded with {varname} to store fd number in varname DEBUG can force skipping following command [[ -v var ]] operator (checks whether or not var is set) typeset -n and `nameref' variables process substitutions work without /dev/fd Section D: Why does bash do some things differently than other Unix shells? D1) Why does bash run a different version of `command' than `which command' says it will? On many systems, `which' is actually a csh script that assumes you're running csh. In tcsh, `which' and its cousin `where' are builtins. On other Unix systems, `which' is a perl script that uses the PATH environment variable. Many Linux distributions use GNU `which', which is a C program that can understand shell aliases. The csh script version reads the csh startup files from your home directory and uses those to determine which `command' will be invoked. Since bash doesn't use any of those startup files, there's a good chance that your bash environment differs from your csh environment. The bash `type' builtin does everything `which' does, and will report correct results for the running shell. If you're really wedded to the name `which', try adding the following function definition to your .bashrc: which() { builtin type "$@" } If you're moving from tcsh and would like to bring `where' along as well, use this function: where() { builtin type -a "$@" } D2) Why doesn't bash treat brace expansions exactly like csh? The only difference between bash and csh brace expansion is that bash requires a brace expression to contain at least one unquoted comma if it is to be expanded. Any brace-surrounded word not containing an unquoted comma is left unchanged by the brace expansion code. This affords the greatest degree of sh compatibility. Bash, ksh, zsh, and pd-ksh all implement brace expansion this way. D3) Why doesn't bash have csh variable modifiers? Posix has specified a more powerful, albeit somewhat more cryptic, mechanism cribbed from ksh, and bash implements it. ${parameter%word} Remove smallest suffix pattern. The WORD is expanded to produce a pattern. It then expands to the value of PARAMETER, with the smallest portion of the suffix matched by the pattern deleted. x=file.c echo ${x%.c}.o -->file.o ${parameter%%word} Remove largest suffix pattern. The WORD is expanded to produce a pattern. It then expands to the value of PARAMETER, with the largest portion of the suffix matched by the pattern deleted. x=posix/src/std echo ${x%%/*} -->posix ${parameter#word} Remove smallest prefix pattern. The WORD is expanded to produce a pattern. It then expands to the value of PARAMETER, with the smallest portion of the prefix matched by the pattern deleted. x=$HOME/src/cmd echo ${x#$HOME} -->/src/cmd ${parameter##word} Remove largest prefix pattern. The WORD is expanded to produce a pattern. It then expands to the value of PARAMETER, with the largest portion of the prefix matched by the pattern deleted. x=/one/two/three echo ${x##*/} -->three Given a=/a/b/c/d b=b.xxx csh bash result --- ---- ------ $a:h ${a%/*} /a/b/c $a:t ${a##*/} d $b:r ${b%.*} b $b:e ${b##*.} xxx D4) How can I make my csh aliases work when I convert to bash? Bash uses a different syntax to support aliases than csh does. The details can be found in the documentation. We have provided a shell script which does most of the work of conversion for you; this script can be found in ./examples/misc/aliasconv.sh. Here is how you use it: Start csh in the normal way for you. (e.g., `csh') Pipe the output of `alias' through `aliasconv.sh', saving the results into `bash_aliases': alias | bash aliasconv.sh >bash_aliases Edit `bash_aliases', carefully reading through any created functions. You will need to change the names of some csh specific variables to the bash equivalents. The script converts $cwd to $PWD, $term to $TERM, $home to $HOME, $user to $USER, and $prompt to $PS1. You may also have to add quotes to avoid unwanted expansion. For example, the csh alias: alias cd 'cd \!*; echo $cwd' is converted to the bash function: cd () { command cd "$@"; echo $PWD ; } The only thing that needs to be done is to quote $PWD: cd () { command cd "$@"; echo "$PWD" ; } Merge the edited file into your ~/.bashrc. There is an additional, more ambitious, script in examples/misc/cshtobash that attempts to convert your entire csh environment to its bash equivalent. This script can be run as simply `cshtobash' to convert your normal interactive environment, or as `cshtobash ~/.login' to convert your login environment. D5) How can I pipe standard output and standard error from one command to another, like csh does with `|&'? Use command 2>&1 | command2 The key is to remember that piping is performed before redirection, so file descriptor 1 points to the pipe when it is duplicated onto file descriptor 2. D6) Now that I've converted from ksh to bash, are there equivalents to ksh features like autoloaded functions and the `whence' command? There are features in ksh-88 and ksh-93 that do not have direct bash equivalents. Most, however, can be emulated with very little trouble. ksh-88 feature Bash equivalent -------------- --------------- compiled-in aliases set up aliases in .bashrc; some ksh aliases are bash builtins (hash, history, type) coprocesses named pipe pairs (one for read, one for write) typeset +f declare -F cd, print, whence function substitutes in examples/functions/kshenv autoloaded functions examples/functions/autoload is the same as typeset -fu read var?prompt read -p prompt var ksh-93 feature Bash equivalent -------------- --------------- sleep, getconf Bash has loadable versions in examples/loadables ${.sh.version} $BASH_VERSION print -f printf hist alias hist=fc $HISTEDIT $FCEDIT Section E: How can I get bash to do certain things, and why does bash do things the way it does? E1) Why is the bash builtin `test' slightly different from /bin/test? The specific example used here is [ ! x -o x ], which is false. Bash's builtin `test' implements the Posix.2 spec, which can be summarized as follows (the wording is due to David Korn): Here is the set of rules for processing test arguments. 0 Args: False 1 Arg: True iff argument is not null. 2 Args: If first arg is !, True iff second argument is null. If first argument is unary, then true if unary test is true Otherwise error. 3 Args: If second argument is a binary operator, do binary test of $1 $3 If first argument is !, negate two argument test of $2 $3 If first argument is `(' and third argument is `)', do the one-argument test of the second argument. Otherwise error. 4 Args: If first argument is !, negate three argument test of $2 $3 $4. Otherwise unspecified 5 or more Args: unspecified. (Historical shells would use their current algorithm). The operators -a and -o are considered binary operators for the purpose of the 3 Arg case. As you can see, the test becomes (not (x or x)), which is false. E2) Why does bash sometimes say `Broken pipe'? If a sequence of commands appears in a pipeline, and one of the reading commands finishes before the writer has finished, the writer receives a SIGPIPE signal. Many other shells special-case SIGPIPE as an exit status in the pipeline and do not report it. For example, in: ps -aux | head `head' can finish before `ps' writes all of its output, and ps will try to write on a pipe without a reader. In that case, bash will print `Broken pipe' to stderr when ps is killed by a SIGPIPE. As of bash-3.1, bash does not report SIGPIPE errors by default. You can build a version of bash that will report such errors. E3) When I have terminal escape sequences in my prompt, why does bash wrap lines at the wrong column? Readline, the line editing library that bash uses, does not know that the terminal escape sequences do not take up space on the screen. The redisplay code assumes, unless told otherwise, that each character in the prompt is a `printable' character that takes up one character position on the screen. You can use the bash prompt expansion facility (see the PROMPTING section in the manual page) to tell readline that sequences of characters in the prompt strings take up no screen space. Use the \[ escape to begin a sequence of non-printing characters, and the \] escape to signal the end of such a sequence. E4) If I pipe the output of a command into `read variable', why doesn't the output show up in $variable when the read command finishes? This has to do with the parent-child relationship between Unix processes. It affects all commands run in pipelines, not just simple calls to `read'. For example, piping a command's output into a `while' loop that repeatedly calls `read' will result in the same behavior. Each element of a pipeline, even a builtin or shell function, runs in a separate process, a child of the shell running the pipeline. A subprocess cannot affect its parent's environment. When the `read' command sets the variable to the input, that variable is set only in the subshell, not the parent shell. When the subshell exits, the value of the variable is lost. Many pipelines that end with `read variable' can be converted into command substitutions, which will capture the output of a specified command. The output can then be assigned to a variable: grep ^gnu /usr/lib/news/active | wc -l | read ngroup can be converted into ngroup=$(grep ^gnu /usr/lib/news/active | wc -l) This does not, unfortunately, work to split the text among multiple variables, as read does when given multiple variable arguments. If you need to do this, you can either use the command substitution above to read the output into a variable and chop up the variable using the bash pattern removal expansion operators or use some variant of the following approach. Say /usr/local/bin/ipaddr is the following shell script: #! /bin/sh host `hostname` | awk '/address/ {print $NF}' Instead of using /usr/local/bin/ipaddr | read A B C D to break the local machine's IP address into separate octets, use OIFS="$IFS" IFS=. set -- $(/usr/local/bin/ipaddr) IFS="$OIFS" A="$1" B="$2" C="$3" D="$4" Beware, however, that this will change the shell's positional parameters. If you need them, you should save them before doing this. This is the general approach -- in most cases you will not need to set $IFS to a different value. Some other user-supplied alternatives include: read A B C D << HERE $(IFS=.; echo $(/usr/local/bin/ipaddr)) HERE and, where process substitution is available, read A B C D < <(IFS=.; echo $(/usr/local/bin/ipaddr)) E5) I have a bunch of shell scripts that use backslash-escaped characters in arguments to `echo'. Bash doesn't interpret these characters. Why not, and how can I make it understand them? This is the behavior of echo on most Unix System V machines. The bash builtin `echo' is modeled after the 9th Edition Research Unix version of `echo'. It does not interpret backslash-escaped characters in its argument strings by default; it requires the use of the -e option to enable the interpretation. The System V echo provides no way to disable the special characters; the bash echo has a -E option to disable them. There is a configuration option that will make bash behave like the System V echo and interpret things like `\t' by default. Run configure with the --enable-xpg-echo-default option to turn this on. Be aware that this will cause some of the tests run when you type `make tests' to fail. There is a shell option, `xpg_echo', settable with `shopt', that will change the behavior of echo at runtime. Enabling this option turns on expansion of backslash-escape sequences. E6) Why doesn't a while or for loop get suspended when I type ^Z? This is a consequence of how job control works on Unix. The only thing that can be suspended is the process group. This is a single command or pipeline of commands that the shell forks and executes. When you run a while or for loop, the only thing that the shell forks and executes are any commands in the while loop test and commands in the loop bodies. These, therefore, are the only things that can be suspended when you type ^Z. If you want to be able to stop the entire loop, you need to put it within parentheses, which will force the loop into a subshell that may be stopped (and subsequently restarted) as a single unit. E7) What about empty for loops in Makefiles? It's fairly common to see constructs like this in automatically-generated Makefiles: SUBDIRS = @SUBDIRS@ ... subdirs-clean: for d in ${SUBDIRS}; do \ ( cd $$d && ${MAKE} ${MFLAGS} clean ) \ done When SUBDIRS is empty, this results in a command like this being passed to bash: for d in ; do ( cd $d && ${MAKE} ${MFLAGS} clean ) done In versions of bash before bash-2.05a, this was a syntax error. If the reserved word `in' was present, a word must follow it before the semicolon or newline. The language in the manual page referring to the list of words being empty referred to the list after it is expanded. These versions of bash required that there be at least one word following the `in' when the construct was parsed. The idiomatic Makefile solution is something like: SUBDIRS = @SUBDIRS@ subdirs-clean: subdirs=$SUBDIRS ; for d in $$subdirs; do \ ( cd $$d && ${MAKE} ${MFLAGS} clean ) \ done The latest updated POSIX standard has changed this: the word list is no longer required. Bash versions 2.05a and later accept the new syntax. E8) Why does the arithmetic evaluation code complain about `08'? The bash arithmetic evaluation code (used for `let', $(()), (()), and in other places), interprets a leading `0' in numeric constants as denoting an octal number, and a leading `0x' as denoting hexadecimal. This is in accordance with the POSIX.2 spec, section 2.9.2.1, which states that arithmetic constants should be handled as signed long integers as defined by the ANSI/ISO C standard. The POSIX.2 interpretation committee has confirmed this: http://www.pasc.org/interps/unofficial/db/p1003.2/pasc-1003.2-173.html E9) Why does the pattern matching expression [A-Z]* match files beginning with every letter except `z'? Bash-2.03, Bash-2.05 and later versions honor the current locale setting when processing ranges within pattern matching bracket expressions ([A-Z]). This is what POSIX.2 and SUSv3/XPG6 specify. The behavior of the matcher in bash-2.05 and later versions depends on the current LC_COLLATE setting. Setting this variable to `C' or `POSIX' will result in the traditional behavior ([A-Z] matches all uppercase ASCII characters). Many other locales, including the en_US locale (the default on many US versions of Linux) collate the upper and lower case letters like this: AaBb...Zz which means that [A-Z] matches every letter except `z'. Others collate like aAbBcC...zZ which means that [A-Z] matches every letter except `a'. The portable way to specify upper case letters is [:upper:] instead of A-Z; lower case may be specified as [:lower:] instead of a-z. Look at the manual pages for setlocale(3), strcoll(3), and, if it is present, locale(1). If you have locale(1), you can use it to find your current locale information even if you do not have any of the LC_ variables set. My advice is to put export LC_COLLATE=C into /etc/profile and inspect any shell scripts run from cron for constructs like [A-Z]. This will prevent things like rm [A-Z]* from removing every file in the current directory except those beginning with `z' and still allow individual users to change the collation order. Users may put the above command into their own profiles as well, of course. E10) Why does `cd //' leave $PWD as `//'? POSIX.2, in its description of `cd', says that *three* or more leading slashes may be replaced with a single slash when canonicalizing the current working directory. This is, I presume, for historical compatibility. Certain versions of Unix, and early network file systems, used paths of the form //hostname/path to access `path' on server `hostname'. E11) If I resize my xterm while another program is running, why doesn't bash notice the change? This is another issue that deals with job control. The kernel maintains a notion of a current terminal process group. Members of this process group (processes whose process group ID is equal to the current terminal process group ID) receive terminal-generated signals like SIGWINCH. (For more details, see the JOB CONTROL section of the bash man page.) If a terminal is resized, the kernel sends SIGWINCH to each member of the terminal's current process group (the `foreground' process group). When bash is running with job control enabled, each pipeline (which may be a single command) is run in its own process group, different from bash's process group. This foreground process group receives the SIGWINCH; bash does not. Bash has no way of knowing that the terminal has been resized. There is a `checkwinsize' option, settable with the `shopt' builtin, that will cause bash to check the window size and adjust its idea of the terminal's dimensions each time a process stops or exits and returns control of the terminal to bash. Enable it with `shopt -s checkwinsize'. E12) Why don't negative offsets in substring expansion work like I expect? When substring expansion of the form ${param:offset[:length} is used, an `offset' that evaluates to a number less than zero counts back from the end of the expanded value of $param. When a negative `offset' begins with a minus sign, however, unexpected things can happen. Consider a=12345678 echo ${a:-4} intending to print the last four characters of $a. The problem is that ${param:-word} already has a well-defined meaning: expand to word if the expanded value of param is unset or null, and $param otherwise. To use negative offsets that begin with a minus sign, separate the minus sign and the colon with a space. E13) Why does filename completion misbehave if a colon appears in the filename? Filename completion (and word completion in general) may appear to behave improperly if there is a colon in the word to be completed. The colon is special to readline's word completion code: it is one of the characters that breaks words for the completer. Readline uses these characters in sort of the same way that bash uses $IFS: they break or separate the words the completion code hands to the application-specific or default word completion functions. The original intent was to make it easy to edit colon-separated lists (such as $PATH in bash) in various applications using readline for input. This is complicated by the fact that some versions of the popular `bash-completion' programmable completion package have problems with the default completion behavior in the presence of colons. The current set of completion word break characters is available in bash as the value of the COMP_WORDBREAKS variable. Removing `:' from that value is enough to make the colon not special to completion: COMP_WORDBREAKS=${COMP_WORDBREAKS//:} You can also quote the colon with a backslash to achieve the same result temporarily. E14) Why does quoting the pattern argument to the regular expression matching conditional operator (=~) cause regexp matching to stop working? In versions of bash prior to bash-3.2, the effect of quoting the regular expression argument to the [[ command's =~ operator was not specified. The practical effect was that double-quoting the pattern argument required backslashes to quote special pattern characters, which interfered with the backslash processing performed by double-quoted word expansion and was inconsistent with how the == shell pattern matching operator treated quoted characters. In bash-3.2, the shell was changed to internally quote characters in single- and double-quoted string arguments to the =~ operator, which suppresses the special meaning of the characters special to regular expression processing (`.', `[', `\', `(', `), `*', `+', `?', `{', `|', `^', and `$') and forces them to be matched literally. This is consistent with how the `==' pattern matching operator treats quoted portions of its pattern argument. Since the treatment of quoted string arguments was changed, several issues have arisen, chief among them the problem of white space in pattern arguments and the differing treatment of quoted strings between bash-3.1 and bash-3.2. Both problems may be solved by using a shell variable to hold the pattern. Since word splitting is not performed when expanding shell variables in all operands of the [[ command, this allows users to quote patterns as they wish when assigning the variable, then expand the values to a single string that may contain whitespace. The first problem may be solved by using backslashes or any other quoting mechanism to escape the white space in the patterns. Bash-4.0 introduces the concept of a `compatibility level', controlled by several options to the `shopt' builtin. If the `compat31' option is enabled, bash reverts to the bash-3.1 behavior with respect to quoting the rhs of the =~ operator. E15) Tell me more about the shell compatibility level. Bash-4.0 introduced the concept of a `shell compatibility level', specified as a set of options to the shopt builtin (compat31, compat32, compat40 at this writing). There is only one current compatibility level -- each option is mutually exclusive. This list does not mention behavior that is standard for a particular version (e.g., setting compat32 means that quoting the rhs of the regexp matching operator quotes special regexp characters in the word, which is default behavior in bash-3.2 and above). compat31 set - the < and > operators to the [[ command do not consider the current locale when comparing strings - quoting the rhs of the regexp matching operator (=~) has no special effect compat32 set - the < and > operators to the [[ command do not consider the current locale when comparing strings compat40 set - the < and > operators to the [[ command do not consider the current locale when comparing strings - interrupting a command list such as "a ; b ; c" causes the execution of the entire list to be aborted (in versions before bash-4.0, interrupting one command in a list caused the next to be executed) compat41 set - interrupting a command list such as "a ; b ; c" causes the execution of the entire list to be aborted (in versions before bash-4.1, interrupting one command in a list caused the next to be executed) - when in posix mode, single quotes in the `word' portion of a double-quoted parameter expansion define a new quoting context and are treated specially compat42 set - the replacement string in double-quoted pattern substitution is not run through quote removal, as in previous versions Section F: Things to watch out for on certain Unix versions F1) Why can't I use command line editing in my `cmdtool'? The problem is `cmdtool' and bash fighting over the input. When scrolling is enabled in a cmdtool window, cmdtool puts the tty in `raw mode' to permit command-line editing using the mouse for applications that cannot do it themselves. As a result, bash and cmdtool each try to read keyboard input immediately, with neither getting enough of it to be useful. This mode also causes cmdtool to not implement many of the terminal functions and control sequences appearing in the `sun-cmd' termcap entry. For a more complete explanation, see that file examples/suncmd.termcap in the bash distribution. `xterm' is a better choice, and gets along with bash much more smoothly. If you must use cmdtool, you can use the termcap description in examples/suncmd.termcap. Set the TERMCAP variable to the terminal description contained in that file, i.e. TERMCAP='Mu|sun-cmd:am:bs:km:pt:li#34:co#80:cl=^L:ce=\E[K:cd=\E[J:rs=\E[s:' Then export TERMCAP and start a new cmdtool window from that shell. The bash command-line editing should behave better in the new cmdtool. If this works, you can put the assignment to TERMCAP in your bashrc file. F2) I built bash on Solaris 2. Why do globbing expansions and filename completion chop off the first few characters of each filename? This is the consequence of building bash on SunOS 5 and linking with the libraries in /usr/ucblib, but using the definitions and structures from files in /usr/include. The actual conflict is between the dirent structure in /usr/include/dirent.h and the struct returned by the version of `readdir' in libucb.a (a 4.3-BSD style `struct direct'). Make sure you've got /usr/ccs/bin ahead of /usr/ucb in your $PATH when configuring and building bash. This will ensure that you use /usr/ccs/bin/cc or acc instead of /usr/ucb/cc and that you link with libc before libucb. If you have installed the Sun C compiler, you may also need to put /usr/ccs/bin and /opt/SUNWspro/bin into your $PATH before /usr/ucb. F3) Why does bash dump core after I interrupt username completion or `~user' tilde expansion on a machine running NIS? This is a famous and long-standing bug in the SunOS YP (sorry, NIS) client library, which is part of libc. The YP library code keeps static state -- a pointer into the data returned from the server. When YP initializes itself (setpwent), it looks at this pointer and calls free on it if it's non-null. So far, so good. If one of the YP functions is interrupted during getpwent (the exact function is interpretwithsave()), and returns NULL, the pointer is freed without being reset to NULL, and the function returns. The next time getpwent is called, it sees that this pointer is non-null, calls free, and the bash free() blows up because it's being asked to free freed memory. The traditional Unix mallocs allow memory to be freed multiple times; that's probably why this has never been fixed. You can run configure with the `--without-gnu-malloc' option to use the C library malloc and avoid the problem. F4) I'm running SVR4.2. Why is the line erased every time I type `@'? The `@' character is the default `line kill' character in most versions of System V, including SVR4.2. You can change this character to whatever you want using `stty'. For example, to change the line kill character to control-u, type stty kill ^U where the `^' and `U' can be two separate characters. F5) Why does bash report syntax errors when my C News scripts use a redirection before a subshell command? The actual command in question is something like < file ( command ) According to the grammar given in the POSIX.2 standard, this construct is, in fact, a syntax error. Redirections may only precede `simple commands'. A subshell construct such as the above is one of the shell's `compound commands'. A redirection may only follow a compound command. This affects the mechanical transformation of commands that use `cat' to pipe a file into a command (a favorite Useless-Use-Of-Cat topic on comp.unix.shell). While most commands of the form cat file | command can be converted to `< file command', shell control structures such as loops and subshells require `command < file'. The file CWRU/sh-redir-hack in the bash distribution is an (unofficial) patch to parse.y that will modify the grammar to support this construct. It will not apply with `patch'; you must modify parse.y by hand. Note that if you apply this, you must recompile with -DREDIRECTION_HACK. This introduces a large number of reduce/reduce conflicts into the shell grammar. F6) Why can't I use vi-mode editing on Red Hat Linux 6.1? The short answer is that Red Hat screwed up. The long answer is that they shipped an /etc/inputrc that only works for emacs mode editing, and then screwed all the vi users by setting INPUTRC to /etc/inputrc in /etc/profile. The short fix is to do one of the following: remove or rename /etc/inputrc, set INPUTRC=~/.inputrc in ~/.bashrc (or .bash_profile, but make sure you export it if you do), remove the assignment to INPUTRC from /etc/profile, add set keymap emacs to the beginning of /etc/inputrc, or bracket the key bindings in /etc/inputrc with these lines $if mode=emacs [...] $endif F7) Why do bash-2.05a and bash-2.05b fail to compile `printf.def' on HP/UX 11.x? HP/UX's support for long double is imperfect at best. GCC will support it without problems, but the HP C library functions like strtold(3) and printf(3) don't actually work with long doubles. HP implemented a `long_double' type as a 4-element array of 32-bit ints, and that is what the library functions use. The ANSI C `long double' type is a 128-bit floating point scalar. The easiest fix, until HP fixes things up, is to edit the generated config.h and #undef the HAVE_LONG_DOUBLE line. After doing that, the compilation should complete successfully. Section G: How can I get bash to do certain common things? G1) How can I get bash to read and display eight-bit characters? This is a process requiring several steps. First, you must ensure that the `physical' data path is a full eight bits. For xterms, for example, the `vt100' resources `eightBitInput' and `eightBitOutput' should be set to `true'. Once you have set up an eight-bit path, you must tell the kernel and tty driver to leave the eighth bit of characters alone when processing keyboard input. Use `stty' to do this: stty cs8 -istrip -parenb For old BSD-style systems, you can use stty pass8 You may also need stty even odd Finally, you need to tell readline that you will be inputting and displaying eight-bit characters. You use readline variables to do this. convert-meta says what to do if you read a character with its eighth bit set. input-meta says whether to permit characters with the eighth bit at all. output-meta determines how to display characters with the eighth bit set: if on, they are output directly; if it is off, such characters are displayed as a meta-prefixed escape sequence. These variables can be set in your .inputrc or using the bash `bind' builtin. Here's an example using `bind': bash$ bind 'set convert-meta off' bash$ bind 'set input-meta on' bash$ bind 'set output-meta on' The `set' commands between the single quotes may also be placed in ~/.inputrc. The script examples/scripts.noah/meta.bash encapsulates the bind commands in a shell function. G2) How do I write a function `x' to replace builtin command `x', but still invoke the command from within the function? This is why the `command' and `builtin' builtins exist. The `command' builtin executes the command supplied as its first argument, skipping over any function defined with that name. The `builtin' builtin executes the builtin command given as its first argument directly. For example, to write a function to replace `cd' that writes the hostname and current directory to an xterm title bar, use something like the following: cd() { builtin cd "$@" && xtitle "$HOST: $PWD" } This could also be written using `command' instead of `builtin'; the version above is marginally more efficient. G3) How can I find the value of a shell variable whose name is the value of another shell variable? Versions of Bash newer than Bash-2.0 support this directly. You can use ${!var} For example, the following sequence of commands will echo `z': var1=var2 var2=z echo ${!var1} For sh compatibility, use the `eval' builtin. The important thing to remember is that `eval' expands the arguments you give it again, so you need to quote the parts of the arguments that you want `eval' to act on. For example, this expression prints the value of the last positional parameter: eval echo \"\$\{$#\}\" The expansion of the quoted portions of this expression will be deferred until `eval' runs, while the `$#' will be expanded before `eval' is executed. In versions of bash later than bash-2.0, echo ${!#} does the same thing. This is not the same thing as ksh93 `nameref' variables, though the syntax is similar. Namerefs are available bash version 4.3, and work as in ksh93. G4) How can I make the bash `time' reserved word print timing output that looks like the output from my system's /usr/bin/time? The bash command timing code looks for a variable `TIMEFORMAT' and uses its value as a format string to decide how to display the timing statistics. The value of TIMEFORMAT is a string with `%' escapes expanded in a fashion similar in spirit to printf(3). The manual page explains the meanings of the escape sequences in the format string. If TIMEFORMAT is not set, bash acts as if the following assignment had been performed: TIMEFORMAT=$'\nreal\t%3lR\nuser\t%3lU\nsys\t%3lS' The POSIX.2 default time format (used by `time -p command') is TIMEFORMAT=$'real %2R\nuser %2U\nsys %2S' The BSD /usr/bin/time format can be emulated with: TIMEFORMAT=$'\t%1R real\t%1U user\t%1S sys' The System V /usr/bin/time format can be emulated with: TIMEFORMAT=$'\nreal\t%1R\nuser\t%1U\nsys\t%1S' The ksh format can be emulated with: TIMEFORMAT=$'\nreal\t%2lR\nuser\t%2lU\nsys\t%2lS' G5) How do I get the current directory into my prompt? Bash provides a number of backslash-escape sequences which are expanded when the prompt string (PS1 or PS2) is displayed. The full list is in the manual page. The \w expansion gives the full pathname of the current directory, with a tilde (`~') substituted for the current value of $HOME. The \W expansion gives the basename of the current directory. To put the full pathname of the current directory into the path without any tilde subsitution, use $PWD. Here are some examples: PS1='\w$ ' # current directory with tilde PS1='\W$ ' # basename of current directory PS1='$PWD$ ' # full pathname of current directory The single quotes are important in the final example to prevent $PWD from being expanded when the assignment to PS1 is performed. G6) How can I rename "*.foo" to "*.bar"? Use the pattern removal functionality described in D3. The following `for' loop will do the trick: for f in *.foo; do mv $f ${f%foo}bar done G7) How can I translate a filename from uppercase to lowercase? The script examples/functions/lowercase, originally written by John DuBois, will do the trick. The converse is left as an exercise. G8) How can I write a filename expansion (globbing) pattern that will match all files in the current directory except "." and ".."? You must have set the `extglob' shell option using `shopt -s extglob' to use this: echo .!(.|) * A solution that works without extended globbing is given in the Unix Shell FAQ, posted periodically to comp.unix.shell. It's a variant of echo .[!.]* ..?* * (The ..?* catches files with names of three or more characters beginning with `..') Section H: Where do I go from here? H1) How do I report bugs in bash, and where should I look for fixes and advice? Use the `bashbug' script to report bugs. It is built and installed at the same time as bash. It provides a standard template for reporting a problem and automatically includes information about your configuration and build environment. `bashbug' sends its reports to bug-bash@gnu.org, which is a large mailing list gatewayed to the usenet newsgroup gnu.bash.bug. Bug fixes, answers to questions, and announcements of new releases are all posted to gnu.bash.bug. Discussions concerning bash features and problems also take place there. To reach the bash maintainers directly, send mail to bash-maintainers@gnu.org. H2) What kind of bash documentation is there? First, look in the doc directory in the bash distribution. It should contain at least the following files: bash.1 an extensive, thorough Unix-style manual page builtins.1 a manual page covering just bash builtin commands bashref.texi a reference manual in GNU tex`info format bashref.info an info version of the reference manual FAQ this file article.ms text of an article written for The Linux Journal readline.3 a man page describing readline Postscript, HTML, and ASCII files created from the above source are available in the documentation distribution. There is additional documentation available for anonymous FTP from host ftp.cwru.edu in the `pub/bash' directory. Cameron Newham and Bill Rosenblatt have written a book on bash, published by O'Reilly and Associates. The book is based on Bill Rosenblatt's Korn Shell book. The title is ``Learning the Bash Shell'', and the ISBN number of the third edition, published in March, 2005, is 0-596-00965-8. Look for it in fine bookstores near you. This edition of the book has been updated to cover bash-3.0. The GNU Bash Reference Manual has been published as a printed book by Network Theory Ltd (Paperback, ISBN: 0-9541617-7-7, Nov. 2006). It covers bash-3.2 and is available from most online bookstores (see http://www.network-theory.co.uk/bash/manual/ for details). The publisher will donate $1 to the Free Software Foundation for each copy sold. Arnold Robbins and Nelson Beebe have written ``Classic Shell Scripting'', published by O'Reilly. The first edition, with ISBN number 0-596-00595-4, was published in May, 2005. Chris F. A. Johnson, a frequent contributor to comp.unix.shell and gnu.bash.bug, has written ``Shell Scripting Recipes: A Problem-Solution Approach,'' a new book on shell scripting, concentrating on features of the POSIX standard helpful to shell script writers. The first edition from Apress, with ISBN number 1-59059-471-1, was published in May, 2005. H3) What's coming in future versions? These are features I hope to include in a future version of bash. Rocky Bernstein's bash debugger (support is included with bash-4.0) H4) What's on the bash `wish list' for future versions? These are features that may or may not appear in a future version of bash. breaking some of the shell functionality into embeddable libraries a module system like zsh's, using dynamic loading like builtins a bash programmer's guide with a chapter on creating loadable builtins a better loadable interface to perl with access to the shell builtins and variables (contributions gratefully accepted) ksh93-like `xx.yy' variables (including some of the .sh.* variables) and associated disipline functions Some of the new ksh93 pattern matching operators, like backreferencing H5) When will the next release appear? The next version will appear sometime in 2015. Never make predictions. This document is Copyright 1995-2014 by Chester Ramey. Permission is hereby granted, without written agreement and without license or royalty fees, to use, copy, and distribute this document for any purpose, provided that the above copyright notice appears in all copies of this document and that the contents of this document remain unaltered. usr/share/doc/ctags/FAQ000064400000041123152531426420010664 0ustar00Frequently Asked Questions ========================== * 1. Why do you call it "Exuberant Ctags"? * 2. Why doesn't my editor work with these tag files? * 3. What are these strange bits of text beginning with ;"? * 4. Why doesn't XEmacs' Speedbar module work with Exuberant Ctags? * 5. Why doesn't Xemacs correctly locate the tag in the source file? * 6. Why doesn't NEdit correctly locate the tag in the source file? * 7. Why can't I jump to "class::member"? * 8. How can I avoid having to specify my favorite option every time? * 9. Why do I end up on the wrong line when I jump to a tag? * 10. How do I jump to the tag I want instead of the wrong one by the same name? * 11. What is "Vim"? * 12. How can I locate all references to a specific function or variable? * 13. Why does appending tags to a tag file tag so long? * 14. How do I get regex support for Win32? * 15. How should I set up tag files for a multi-level directory hierarchy? ---------------------------------------------------------------------- 1. Why do you call it "Exuberant Ctags"? Because one of the meanings of the word "exuberant" is: exuberant : produced in extreme abundance : PLENTIFUL syn see PROFUSE Compare the tag file produced by Exuberant Ctags with that produced by any other ctags and you will see how appropriate the name is. ---------------------------------------------------------------------- 2. Why doesn't my editor work with these tag files? 3. What are these strange bits of text beginning with ;" which follow many of the lines in the tag file? These are "extension flags". They are added in order to provide extra information about the tag that may be utilized by the editor in order to more intelligently handle tags. They are appended to the EX command part of the tag line in a manner that provides backwards compatibility with existing implementations of the Vi editor. The semicolon is an EX command separator and the double quote begins an EX comment. Thus, the extension flags appear as an EX comment and should be ignored by the editor when it processes the EX command. Some non-vi editors, however, implement only the bare minimum of EX commands in order to process the search command or line number in the third field of the tag file. If you encounter this problem, use the option "--format=1" to generate a tag file without these extensions (remember that you can set the CTAGS environment variable to any default arguments you wish to supply). Then ask the supplier of your editor to implement handling of this feature of EX commands. ---------------------------------------------------------------------- 4. Why doesn't XEmacs' Speedbar module work with Exuberant Ctags? The default command line switches used by XEmacs for "etags" are not compatible with Exuberant Ctags options. By default, Exuberant Ctags installs a symbolic link, "etags", pointing to the ctags executable. When Exuberant Ctags is started with the name "etags", it produces Emacs-style tag files by default. To fix this, add the following lines to your .emacs file, replacing the path to "etags" with the path where the symbolic link was installed. (autoload 'speedbar "speedbar") (setq speedbar-fetch-etags-command "/usr/local/bin/etags" speedbar-fetch-etags-arguments '("-f" "-")) ---------------------------------------------------------------------- 5. Why doesn't Xemacs correctly locate the tag in the source file? This has been observed with version 20.3. It seems that when Xemacs searches for a tag, it searches using the tag name instead of the search string located in the TAGS file. This is a bug in Xemacs and does not occur in the GNU version of Emacs. ---------------------------------------------------------------------- 6. Why doesn't NEdit correctly locate the tag in the source file? Versions of NEdit prior to 5.1 did not support the extended tag file format generated by Exuberant Ctags by default. Either upgrade to version 5.1 or specify the option "--format=1" when running ctags to output the old tag file format. ---------------------------------------------------------------------- 7. Why can't I jump to "class::member"? Because, by default, ctags only generates tags for the separate identifiers found in the source files. If you specify the --extra=+q option, then ctags will also generate a second, class-qualified tag for each class member (data and function/method) in the form class::member for C++, and in the form class.method for Eiffel and Java. ---------------------------------------------------------------------- 8. How can I avoid having to specify my favorite option every time? Either by setting the environment variable CTAGS to your custom options, or putting them into a .ctags file in your home directory. ---------------------------------------------------------------------- 9. Why do I end up on the wrong line when I jump to a tag? By default, ctags encodes the line number in the file where macro (#define) tags are found. This was done to remain compatible with the original UNIX version of ctags. If you change the file containing the tag without rebuilding the tag file, the location of tag in the tag file may no longer match the current location. In order to avoid this problem, you can specify the option "--excmd=p", which causes ctags to use a search pattern to locate macro tags. I have never uncovered the reason why the original UNIX ctags used line numbers exclusively for macro tags, but have so far resisted changing the default behaviour of Exuberant Ctags to behave differently. ---------------------------------------------------------------------- 10. How do I jump to the tag I want instead of the wrong one by the same name? A tag file is simple a list of tag names and where to find them. If there are duplicate entries, you often end up going to the wrong one because the tag file is sorted and your editor locates the first one in the tag file. Standard Vi provides no facilities to alter this behavior. However, Vim has some nice features to minimize this problem, primarly by examining all matches and choosing the best one under the circumstances. Vim also provides commands which allow for selection of the desired matching tag. ---------------------------------------------------------------------- 11. What is "Vim"? Vim is a vi-compatible editor available as source and compilable for any platform. Yeah, I know the first reaction is to shy away from this. But you will never regret getting it, and you will become greatly attached to its features, which you can learn gradually. I would be willing to say that it is the best vi-clone available within 4 light-years of Alpha Centauri. It works (nearly) exactly like standard vi, but provides some incredibly useful extensions (some of which I have participated in designing with the author). Most Linux distributions have adopted Vim as its standard vi. ---------------------------------------------------------------------- 12. How can I locate all references to a specific function or variable? There are several packages already available which provide this capability. Namely, these are: GLOBAL source code tag system, GNU id-utils, cscope, and cflow. As of this writing, they can be found in the following locations: GLOBAL: http://www.gnu.org/software/global id-utils: http://www.gnu.org/software/idutils/idutils.html cscope: http://cscope.sourceforge.net cflow: ftp://www.ibiblio.org/pub/Linux/devel/lang/c ---------------------------------------------------------------------- 13. Why does appending tags to a tag file tag so long? Sometimes, in an attempt to build a global tag file for all source files in a large source tree of many directories, someone will make an attempt to run ctags in append (-a) mode on every directory in the hierarchy. Each time ctags is invoked, its default behavior is to sort the tag file once the tags for that execution have been added. As the cumulative tag file grows, the sort time increases arithmetically. The best way to avoid this problem (and the most efficient) is to make use of the --recurse (or -R) option of ctags by executing the following command in the root of the directory hierarchy (thus running ctags only once): ctags -R If you really insist on running ctags separately on each directory, you can avoid the sort pass each time by specifying the option "--sort=no". Once the tag file is completely built, use the sort command to manually sort the final tag file, or let the final invocation of ctags sort the file. ---------------------------------------------------------------------- 14. How do I get regex support for Win32? You need to download the GNU regex package for Win32 from the following location: http://people.delphiforums.com/gjc/gnu_regex.html Then point the makefile macro, REGEX_DIR, found in mk_mvc.mak and mk_bc5.mak, to the directory created by extracting this archive. ---------------------------------------------------------------------- 15. How should I set up tag files for a multi-level directory hierarchy? There are a few ways of approaching this: 1. A local tag file in each directory containing only the tags for source files in that directory. 2. One single big, global tag file present in the root directory of your hierarchy, containing all tags present in all source files in the hierarchy. 3. A local tag file in each directory containing only the tags for source files in that directory, in addition to one single global tag file present in the root directory of your hierarchy, containing all non-static tags present in all source files in the hierarchy. 4. A local tag file in each directory of the hierarchy, each one containing all tags present in source files in that directory and all non-static tags in every directory below it (note that this implies also having one big tag file in the root directory of the hierarchy). Each of these approaches has its own set of advantages and disadvantages, depending upon your particular conditions. Which approach is deemed best depends upon the following factors: A. The ability of your editor to use multiple tag files. If your editor cannot make use of multiple tag files (original vi implementations could not), then one large tag file is the only way to go if you ever desire to jump to tags located in other directories. If you never need to jump to tags in another directory (i.e. the source in each directory is entirely self-contained), then a local tag file in each directory will fit your needs. B. The time is takes for your editor to look up a tag in the tag file. The significance of this factor depends upon the size of your source tree and on whether the source files are located on a local or remote file system. For source and tag files located on a local file system, looking up a tag is not as big a hit as one might first imagine, since vi implementations typically perform a binary search on a sorted tag file. This may or may not be true for the editor you use. For files located on a remote file system, reading a large file is an expensive operation. C. Whether or not you expect the source code to change and the time it takes to rebuild a tag file to account for changes to the source code. While Exuberant Ctags is particularly fast in scanning source code (around 1-2 MB/sec), a large project may still result in objectionable delays if one wishes to keep their tag file(s) up to date on a frequent basis, or if the files are located on a remote file system. D. The presence of duplicate tags in the source code and the ability to handle them. The impact of this factor is influenced by the following three issues: 1. How common are duplicate tags in your project? 2. Does your editor provide any facilities for dealing with duplicate tags? While standard vi does not, many modern vi implementations, such as Vim have good facilities for selecting the desired match from the list of duplicates. If your editor does not support duplicate tags, then it will typically send you to only one of them, whether or not that is the one you wanted (and not even notifying you that there are other potential matches). 3. What is the significance of duplicate tags? For example, if you have two tags of the same name from entirely isolated software components, jumping first to the match found in component B while working in component A may be entirely misleading, distracting or inconvenient (to keep having to choose which one if your editor provides you with a list of matches). However, if you have two tags of the same name for parallel builds (say two initialization routines for different hosts), you may always want to specify which one you want. Of the approaches listed above, I tend to favor Approach 3. My editor of choice is Vim, which provides a rich set of features for handling multiple tag files, which partly influences my choice. If you are working with source files on a remote file system, then I would recommend either Approach 3 or Approach 4, depending upon the hit when reading the global tag file. The advantages of Approach 3 are many (assuming that your editor has the ability to support both multiple tag files and duplicate tags). All lookups of tag located in the currect directory are fast and the local tag file can be quickly and easily regenerated in one second or less (I have even mapped a keystroke to do this easily). A lookup of a (necessarily non-static) tag found in another directory fails a lookup in the local tag file, but is found in the global tag file, which satisfies all cross-directory lookups. The global tag file can be automatically regenerated periodically with a cron job (and perhaps the local tag files also). Now I give an example of how you would implement Approach 3. Means of implementing the other approaches can be performed in a similar manner. Here is a visual representation of an example directory hierarchy: project `-----misccomp | `... `-----sysint `-----client | `-----hdrs | `-----lib | `-----src | `-----test `-----common | `-----hdrs | `-----lib | `-----src | `-----test `-----server `-----hdrs `-----lib `-----src `-----test Here is a recommended solution (conceptually) to build the tag files: 1. Within each of the leaf nodes (i.e. hdrs, lib, src, test) build a tag file using "ctags *.[ch]". This can be easily be done for the whole hierarchy by making a shell script, call it "dirtags", containing the following lines: #!/bin/sh cd $1 ctags * Now execute the following command: find * -type d -exec dirtags {} \; These tag files are trivial (and extremely quick) to rebuild while making changes within a directory. The following Vim key mapping is quite useful to rebuild the tag file in the directory of the current source file: :nmap ,t :!(cd %:p:h;ctags *.[ch])& 2. Build the global tag file: cd ~/project ctags --file-scope=no -R thus constructing a tag file containing only non-static tags for all source files in all descendent directories. 3. Configure your editor to read the local tag file first, then consult the global tag file when not found in the local tag file. In Vim, this is done as follows: :set tags=./tags,tags,~/project/tags If you wish to implement Approach 4, you would need to replace the "dirtags" script of step 1 with the following: #!/bin/sh cd $1 ctags * # Now append the non-static tags from descendent directories find * -type d -prune -print | ctags -aR --file-scope=no -L- And replace the configuration of step 3 with this: :set tags=./tags,./../tags,./../../tags,./../../../tags,tags As a caveat, it should be noted that step 2 builds a global tag file whose file names will be relative to the directory in which the global tag file is being built. This takes advantage of the Vim 'tagrelative' option, which causes the path to be interpreted a relative to the location of the tag file instead of the current directory. For standard vi, which always interprets the paths as relative to the current directory, we need to build the global tag file with absolute path names. This can be accomplished by replacing step 2 with the following: cd ~/project ctags --file-scope=no -R `pwd` -- usr/share/doc/dnsmasq/FAQ000064400000065601152531445510011241 0ustar00Q: Why does dnsmasq open UDP ports >1024 as well as port 53. Is this a security problem/trojan/backdoor? A: The high ports that dnsmasq opens are for replies from the upstream nameserver(s). Queries from dnsmasq to upstream nameservers are sent from these ports and replies received to them. The reason for doing this is that most firewall setups block incoming packets _to_ port 53, in order to stop DNS queries from the outside world. If dnsmasq sent its queries from port 53 the replies would be _to_ port 53 and get blocked. This is not a security hole since dnsmasq will only accept replies to that port: queries are dropped. The replies must be to outstanding queries which dnsmasq has forwarded, otherwise they are dropped too. Addendum: dnsmasq now has the option "query-port" (-Q), which allows you to specify the UDP port to be used for this purpose. If not specified, the operating system will select an available port number just as it did before. Second addendum: following the discovery of a security flaw in the DNS protocol, dnsmasq from version 2.43 has changed behavior. It now uses a new, randomly selected, port for each query. The old default behaviour (use one port allocated by the OS) is available by setting --query-port=0, and setting the query port to a positive value still works. You should think hard and know what you are doing before using either of these options. Q: Why doesn't dnsmasq support DNS queries over TCP? Don't the RFC's specify that? A: Update: from version 2.10, it does. There are a few limitations: data obtained via TCP is not cached, and source-address or query-port specifications are ignored for TCP. Q: When I send SIGUSR1 to dump the contents of the cache, some entries have no IP address and are for names like mymachine.mydomain.com.mydomain.com. What are these? A: They are negative entries: that's what the N flag means. Dnsmasq asked an upstream nameserver to resolve that address and it replied "doesn't exist, and won't exist for hours" so dnsmasq saved that information so that if _it_ gets asked the same question it can answer directly without having to go back to the upstream server again. The strange repeated domains result from the way resolvers search short names. See "man resolv.conf" for details. Q: Will dnsmasq compile/run on non-Linux systems? A: Yes, there is explicit support for *BSD and MacOS X and Solaris. There are start-up scripts for MacOS X Tiger and Panther in /contrib. Dnsmasq will link with uclibc to provide small binaries suitable for use in embedded systems such as routers. (There's special code to support machines with flash filesystems and no battery-backed RTC.) If you encounter make errors with *BSD, try installing gmake from ports and building dnsmasq with "make MAKE=gmake" For other systems, try altering the settings in config.h. Q: My company's nameserver knows about some names which aren't in the public DNS. Even though I put it first in /etc/resolv.conf, it doesn't work: dnsmasq seems not to use the nameservers in the order given. What am I doing wrong? A: By default, dnsmasq treats all the nameservers it knows about as equal: it picks the one to use using an algorithm designed to avoid nameservers which aren't responding. To make dnsmasq use the servers in order, give it the -o flag. If you want some queries sent to a special server, think about using the -S flag to give the IP address of that server, and telling dnsmasq exactly which domains to use the server for. Q: OK, I've got queries to a private nameserver working, now how about reverse queries for a range of IP addresses? A: Use the standard DNS convention of .in-addr.arpa. For instance to send reverse queries on the range 192.168.0.0 to 192.168.0.255 to a nameserver at 10.0.0.1 do server=/0.168.192.in-addr.arpa/10.0.0.1 Note that the "bogus-priv" option take priority over this option, so the above will not work when the bogus-priv option is set. Q: Dnsmasq fails to start with an error like this: "dnsmasq: bind failed: Cannot assign requested address". What's the problem? A: This has been seen when a system is bringing up a PPP interface at boot time: by the time dnsmasq start the interface has been created, but not brought up and assigned an address. The easiest solution is to use --interface flags to specify which interfaces dnsmasq should listen on. Since you are unlikely to want dnsmasq to listen on a PPP interface and offer DNS service to the world, the problem is solved. Q: I'm running on BSD and dnsmasq won't accept long options on the command line. A: Dnsmasq when built on some BSD systems doesn't use GNU getopt by default. You can either just use the single-letter options or change config.h and the Makefile to use getopt-long. Note that options in /etc/dnsmasq.conf must always be the long form, on all platforms. Q: Names on the internet are working fine, but looking up local names from /etc/hosts or DHCP doesn't seem to work. A: Resolver code sometime does strange things when given names without any dots in. Win2k and WinXP may not use the DNS at all and just try and look up the name using WINS. On unix look at "options ndots:" in "man resolv.conf" for details on this topic. Testing lookups using "nslookup" or "dig" will work, but then attempting to run "ping" will get a lookup failure, appending a dot to the end of the hostname will fix things. (ie "ping myhost" fails, but "ping myhost." works. The solution is to make sure that all your hosts have a domain set ("domain" in resolv.conf, or set a domain in your DHCP server, see below for Windows XP and Mac OS X). Any domain will do, but "localnet" is traditional. Now when you resolve "myhost" the resolver will attempt to look up "myhost.localnet" so you need to have dnsmasq reply to that name. The way to do that is to include the domain in each name on /etc/hosts and/or to use the --expand-hosts and --domain options. Q: How do I set the DNS domain in Windows XP or MacOS X (ref: previous question)? A: for XP, Control Panel > Network Connections > { Connection to gateway / DNS } > Properties > { Highlight TCP/IP } > Properties > Advanced > DNS Tab > DNS suffix for this connection: A: for OS X, System Preferences > Network > {Connection to gateway / DNS } > Search domains: Q: Can I get dnsmasq to save the contents of its cache to disk when I shut my machine down and re-load when it starts again? A: No, that facility is not provided. Very few names in the DNS have their time-to-live set for longer than a few hours so most of the cache entries would have expired after a shutdown. For longer-lived names it's much cheaper to just reload them from the upstream server. Note that dnsmasq is not shut down between PPP sessions so go off-line and then on-line again will not lose the contents of the cache. Q: Who are Verisign, what do they have to do with the bogus-nxdomain option in dnsmasq and why should I wory about it? A: [note: this was written in September 2003, things may well change.] Verisign run the .com and .net top-level-domains. They have just changed the configuration of their servers so that unknown .com and .net domains, instead of returning an error code NXDOMAIN, (no such domain) return the address of a host at Verisign which runs a web server showing a search page. Most right-thinking people regard this new behaviour as broken :-). You can test to see if you are suffering Verisign brokenness by run a command like host jlsdajkdalld.com If you get "jlsdajkdalld.com" does not exist, then all is fine, if host returns an IP address, then the DNS is broken. (Try a few different unlikely domains, just in case you picked a weird one which really _is_ registered.) Assuming that your DNS is broken, and you want to fix it, simply note the IP address being returned and pass it to dnsmasq using the --bogus-nxdomain flag. Dnsmasq will check for results returning that address and substitute an NXDOMAIN instead. As of writing, the IP address in question for the .com and .net domains is is 64.94.110.11. Various other, less prominent, registries pull the same stunt; there is a list of them all, and the addresses to block, at http://winware.org/bogus-domains.txt Q: This new DHCP server is well and good, but it doesn't work for me. What's the problem? A: There are a couple of configuration gotchas which have been encountered by people moving from the ISC dhcpd to the dnsmasq integrated DHCP daemon. Both are related to differences in in the way the two daemons bypass the IP stack to do "ground up" IP configuration and can lead to the dnsmasq daemon failing whilst the ISC one works. The first thing to check is the broadcast address set for the ethernet interface. This is normally the address on the connected network with all ones in the host part. For instance if the address of the ethernet interface is 192.168.55.7 and the netmask is 255.255.255.0 then the broadcast address should be 192.168.55.255. Having a broadcast address which is not on the network to which the interface is connected kills things stone dead. The second potential problem relates to firewall rules: since the ISC daemon in some configurations bypasses the kernel firewall rules entirely, the ability to run the ISC daemon does not indicate that the current configuration is OK for the dnsmasq daemon. For the dnsmasq daemon to operate it's vital that UDP packets to and from ports 67 and 68 and broadcast packets with source address 0.0.0.0 and destination address 255.255.255.255 are not dropped by iptables/ipchains. Q: I'm running Debian, and my machines get an address fine with DHCP, but their names are not appearing in the DNS. A: By default, none of the DHCP clients send the host-name when asking for a lease. For most of the clients, you can set the host-name to send with the "hostname" keyword in /etc/network/interfaces. (See "man interfaces" for details.) That doesn't work for dhclient, were you have to add something like "send host-name daisy" to /etc/dhclient.conf [Update: the latest dhcpcd packages _do_ send the hostname by default. Q: I'm network booting my machines, and trying to give them static DHCP-assigned addresses. The machine gets its correct address whilst booting, but then the OS starts and it seems to get allocated a different address. A: What is happening is this: The boot process sends a DHCP request and gets allocated the static address corresponding to its MAC address. The boot loader does not send a client-id. Then the OS starts and repeats the DHCP process, but it it does send a client-id. Dnsmasq cannot assume that the two requests are from the same machine (since the client ID's don't match) and even though the MAC address has a static allocation, that address is still in use by the first incarnation of the machine (the one from the boot, without a client ID.) dnsmasq therefore has to give the machine a dynamic address from its pool. There are three ways to solve this: (1) persuade your DHCP client not to send a client ID, or (2) set up the static assignment to the client ID, not the MAC address. The default client-id will be 01:, so change the dhcp-host line from "dhcp-host=11:22:33:44:55:66,1.2.3.4" to "dhcp-host=id:01:11:22:33:44:55:66,1.2.3.4" or (3) tell dnsmasq to ignore client IDs for a particular MAC address, like this: dhcp-host=11:22:33:44:55:66,id:* Q: What network types are supported by the DHCP server? A: Ethernet (and 802.11 wireless) are supported on all platforms. On Linux all network types (including FireWire) are supported. Q: What are these strange "bind-interface" and "bind-dynamic" options? A: Dnsmasq from v2.63 can operate in one of three different "networking modes". This is unfortunate as it requires users configuring dnsmasq to take into account some rather bizarre constraints and select the mode which best fits the requirements of a particular installation. The origin of these are deficiencies in the Unix networking model and APIs and each mode has different advantages and problems. Just to add to the confusion, not all modes are available on all platforms (due the to lack of supporting network APIs).To further add to the confusion, the rules for the DHCP subsystem on dnsmasq are different to the rules for the DNS and TFTP subsystems. The three modes are "wildcard", "bind-interfaces" and "bind-dynamic". In "wildcard" mode, dnsmasq binds the wildcard IP address (0.0.0.0 or ::). This allows it to receive all the packets sent to the server on the relevant port. Access control (--interface, --except-interface, --listen-address, etc) is implemented by dnsmasq: it queries the kernel to determine the interface on which a packet was received and the address to which it was sent, and applies the configured rules. Wildcard mode is the default if neither of the other modes are specified. In "bind-interfaces" mode, dnsmasq runs through all the network interfaces available when it starts, finds the set of IP addresses on those interfaces, filters that set using the access control configuration, and then binds the set of IP addresses. Only packets sent to the allowed addresses are delivered by the kernel to dnsmasq. In "bind-dynamic" mode, access control filtering is done both by binding individual IP addresses, as for bind-interfaces, and by inspecting individual packets on arrival as for wildcard mode. In addition, dnsmasq notices when new interfaces appear or new addresses appear on existing interfaces, and the resulting IP addresses are bound automatically without having to restart dnsmasq. The mode chosen has four different effects: co-existence with other servers, semantics of --interface access control, effect of new interfaces, and legality of --interface specifications for non-existent interfaces. We will deal with these in order. A dnsmasq instance running in wildcard mode precludes a machine from running a second instance of dnsmasq or any other DNS, TFTP or DHCP server. Attempts to do so will fail with an "address in use" error. Dnsmasq running in --bind-interfaces or bind-dynamic mode allow other instances of dnsmasq or other servers, as long as no two servers are configured to listen on the same interface address. The semantics of --interface varies subtly between wildcard or bind-dynamic mode and bind-interfaces mode. The situation where this matters is a request which arrives via one interface (A), but with a destination address of a second interface (B) and when dnsmasq is configured to listen only on B. In wildcard or bind-dynamic mode, such a request will be ignored, in bind-interfaces mode, it will be accepted. The creation of new network interfaces after dnsmasq starts is ignored by dnsmasq when in --bind-interfaces mode. In wildcard or bind-dynamic mode, such interfaces are handled normally. An --interface specification for a non-existent interface is a fatal error at start-up when in --bind-interfaces mode, by just generates a warning in wildcard or bind-dynamic mode. Q: Why doesn't Kerberos work/why can't I get sensible answers to queries for SRV records. A: Probably because you have the "filterwin2k" option set. Note that it was on by default in example configuration files included in versions before 2.12, so you might have it set on without realising. Q: Can I get email notification when a new version of dnsmasq is released? A: Yes, new releases of dnsmasq are always announced through freshmeat.net, and they allow you to subscribe to email alerts when new versions of particular projects are released. New releases are also announced in the dnsmasq-discuss mailing list, subscribe at http://lists.thekelleys.org.uk/mailman/listinfo/dnsmasq-discuss Q: What does the dhcp-authoritative option do? A: The DHCP spec says that when a DHCP server receives a renewal request from a client it has no knowledge of, it should just ignore it. This is because it's supported to have more than one DHCP server on a network, and another DHCP server may be dealing with the client. This has the unfortunate effect that when _no_ DHCP replies to the client, it takes some time for the client to time-out and start to get a new lease. Setting this option makes dnsmasq violate the standard to the extent that it will send a NAK reply to the client, causing it to immediately start to get a new lease. This improves behaviour when machines move networks, and in the case that the DHCP lease database is lost. As long as there are not more tha one DHCP server on the network, it's safe to enable the option. Q: Why does my Gentoo box pause for a minute before getting a new lease? A: Because when a Gentoo box shuts down, it releases its lease with the server but remembers it on the client; this seems to be a Gentoo-specific patch to dhcpcd. On restart it tries to renew a lease which is long gone, as far as dnsmasq is concerned, and dnsmasq ignores it until is times out and restarts the process. To fix this, set the dhcp-authoritative flag in dnsmasq. Q: My laptop has two network interfaces, a wired one and a wireless one. I never use both interfaces at the same time, and I'd like the same IP and configuration to be used irrespective of which interface is in use. How can I do that? A: By default, the identity of a machine is determined by using the MAC address, which is associated with interface hardware. Once an IP is bound to the MAC address of one interface, it cannot be associated with another MAC address until after the DHCP lease expires. The solution to this is to use a client-id as the machine identity rather than the MAC address. If you arrange for the same client-id to sent when either interface is in use, the DHCP server will recognise the same machine, and use the same address. The method for setting the client-id varies with DHCP client software, dhcpcd uses the "-I" flag. Windows uses a registry setting, see http://www.jsiinc.com/SUBF/TIP2800/rh2845.htm Addendum: From version 2.46, dnsmasq has a solution to this which doesn't involve setting client-IDs. It's possible to put more than one MAC address in a --dhcp-host configuration. This tells dnsmasq that it should use the specified IP for any of the specified MAC addresses, and furthermore it gives dnsmasq permission to summarily abandon a lease to one of the MAC addresses if another one comes along. Note that this will work fine only as longer as only one interface is up at any time. There is no way for dnsmasq to enforce this constraint: if you configure multiple MAC addresses and violate this rule, bad things will happen. Addendum-II: The link above is dead, the former contents of the link are: ------------------------------------------------------------------------------ How can I keep the same DHCP client reservation, if the MAC address changes? When you reserve an IP address for a DHCP client, you provide the MAC address of the client's NIC. It is possible to use a custom identifier, which is sent as option 61 in the client's DHCP Discover and Request packet. The DhcpClientIdentifier is a REG_DWORD value that is located at: Windows NT 4.0 SP2+ HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\'X'\Parameters\Tcpip where is the NIC driver name and 'X' is the number of the NIC. Windows 2000 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\TcpIp\Parameters\Interfaces\ where is the GUID of the NIC. The valid range of data is 0x0 - 0xFFFFFFFF. The custom identifier is send as 4 bytes, 8 hexadecimal character, in groups of 2 hexadecimal characters, with the groups being sent in reverse order. If the custom identifier is less than 8 hexadeciaml characters, it is zero padded at the end. Examples: Custom Client Client Reservation Identifier on DHCP Server 12345678 78563412 123456 56341200 1234 34120000 1234567 67452301 12345 45230100 123 23010000 A18F42 428FA100 CF432 32F40C00 C32D1BE BED1320C ------------------------------------------------------------------------------------------------------- Q: Can dnsmasq do DHCP on IP-alias interfaces? A: Yes, from version-2.21. The support is only available running under Linux, on a kernel which provides the RT-netlink facility. All 2.4 and 2.6 kernels provide RT-netlink and it's an option in 2.2 kernels. If a physical interface has more than one IP address or aliases with extra IP addresses, then any dhcp-ranges corresponding to these addresses can be used for address allocation. So if an interface has addresses 192.168.1.0/24 and 192.168.2.0/24 and there are DHCP ranges 192.168.1.100-192.168.1.200 and 192.168.2.100-192.168.2.200 then both ranges would be used for host connected to the physical interface. A more typical use might be to have one of the address-ranges as static-only, and have known hosts allocated addresses on that subnet using dhcp-host options, while anonymous hosts go on the other. Q: Dnsmasq sometimes logs "nameserver xxx.xxx.xxx.xxx refused to do a recursive query" and DNS stops working. What's going on? A: Probably the nameserver is an authoritative nameserver for a particular domain, but is not configured to answer general DNS queries for an arbitrary domain. It is not suitable for use by dnsmasq as an upstream server and should be removed from the configuration. Note that if you have more than one upstream nameserver configured dnsmasq will load-balance across them and it may be some time before dnsmasq gets around to using a particular nameserver. This means that a particular configuration may work for sometime with a broken upstream nameserver configuration. Q: Does the dnsmasq DHCP server probe addresses before allocating them, as recommended in RFC2131? A: Yes, dynamically allocated IP addresses are checked by sending an ICMP echo request (ping). If a reply is received, then dnsmasq assumes that the address is in use, and attempts to allocate an different address. The wait for a reply is between two and three seconds. Because the DHCP server is not re-entrant, it cannot serve other DHCP requests during this time. To avoid dropping requests, the address probe may be skipped when dnsmasq is under heavy load. Q: I'm using dnsmasq on a machine with the Firestarter firewall, and DHCP doesn't work. What's the problem? A: This a variant on the iptables problem. Explicit details on how to proceed can be found at http://lists.thekelleys.org.uk/pipermail/dnsmasq-discuss/2005q3/000431.html Q: I'm using dnsmasq on a machine with the shorewall firewall, and DHCP doesn't work. What's the problem? A: This a variant on the iptables problem. Explicit details on how to proceed can be found at http://lists.thekelleys.org.uk/pipermail/dnsmasq-discuss/2007q4/001764.html Q: Dnsmasq fails to start up with a message about capabilities. Why did that happen and what can do to fix it? A: Change your kernel configuration: either deselect CONFIG_SECURITY _or_ select CONFIG_SECURITY_CAPABILITIES. Alternatively, you can remove the need to set capabilities by running dnsmasq as root. Q: Where can I get .rpms Suitable for openSUSE/SLES? A: Dnsmasq is in openSUSE itself, and the latest releases are also available at http://download.opensuse.org/repositories/network/ Q: Can I run dnsmasq in a Linux vserver? A: Yes, as a DNS server, dnsmasq will just work in a vserver. To use dnsmasq's DHCP function you need to give the vserver extra system capabilities. Please note that doing so will lesser the overall security of your system. The capabilities required are NET_ADMIN and NET_RAW. NET_ADMIN is essential, NET_RAW is required to do an ICMP "ping" check on newly allocated addresses. If you don't need this check, you can disable it with --no-ping and omit the NET_RAW capability. Adding the capabilities is done by adding them, one per line, to either /etc/vservers//ccapabilities for a 2.4 kernel or /etc/vservers//bcapabilities for a 2.6 kernel (please refer to the vserver documentation for more information). Q: What's the problem with syslog and dnsmasq? A: In almost all cases: none. If you have the normal arrangement with local daemons logging to a local syslog, which then writes to disk, then there's never a problem. If you use network logging, then there's a potential problem with deadlock: the syslog daemon will do DNS lookups so that it can log the source of log messages, these lookups will (depending on exact configuration) go through dnsmasq, which also sends log messages. With bad timing, you can arrive at a situation where syslog is waiting for dnsmasq, and dnsmasq is waiting for syslog; they will both wait forever. This problem is fixed from dnsmasq-2.39, which introduces asynchronous logging: dnsmasq no longer waits for syslog and the deadlock is broken. There is a remaining problem in 2.39, where "log-queries" is in use. In this case most DNS queries generate two log lines, if these go to a syslog which is doing a DNS lookup for each log line, then those queries will in turn generate two more log lines, and a chain reaction runaway will occur. To avoid this, use syslog-ng and turn on syslog-ng's dns-cache function. Q: DHCP doesn't work with windows Vista, but everything else is fine. A: The DHCP client on windows Vista (and possibly later versions) demands that the DHCP server send replies as broadcasts. Most other clients don't do this. The broadcasts are send to 255.255.255.255. A badly configured firewall which blocks such packets will show exactly these symptoms (Vista fails, others work). Q: DHCP doesn't work with windows 7 but everything else is fine. A: There seems to be a problem if Windows 7 doesn't get a value for DHCP option 252 in DHCP packets it gets from the server. The symptoms have been variously reported as continual DHCPINFORM requests in an attempt to get an option-252, or even ignoring DHCP offers completely (and failing to get an IP address) if there is no option-252 supplied. DHCP option 252 is for WPAD, WWW Proxy Auto Detection and if you don't want or need to use that, then simplest fix seems to be to supply an empty option with: dhcp-option=252,"\n" usr/share/doc/net-snmp-libs/FAQ000064400000517105152531774110012265 0ustar00 Frequently Asked Questions (FAQ) for the UCD/Net-SNMP package ============================================================= FAQ Author: Dave Shield Net-SNMP Version: 5.8 Net-SNMP/UCD-SNMP Project Leader: Wes Hardaker Email: net-snmp-coders@lists.sourceforge.net TABLE OF CONTENTS ================= TABLE OF CONTENTS GENERAL What is it? Where can I get it? What documentation is available? Are there binaries available? What's the difference between UCD-SNMP and Net-SNMP? What operating systems does it run on? What happens if mine isn't listed? Does it run on Windows? How do I find out about new releases? How can I find out what other people are doing? How do I submit a patch or bug report? Can I reuse the code in my commercial application? What's the difference between SNMPv1, SNMPv2 and SNMPv3? What's the difference between SNMPv2 and SNMPv2c? Which versions of SNMP are supported in this package? Can I use SNMPv1 requests with an SNMPv2 MIB (or vice versa)? How can I monitor my system with SNMP? Where can I find more information about network management? What ports does SNMP use? Is Net-SNMP thread safe? APPLICATIONS How do I add a MIB? How do I add a MIB to the tools? Why can't I see anything from the agent? Why doesn't the agent respond? I can see the system group, but nothing else. Why? Why can't I see values in the tree? The agent worked for a while, then stopped responding. Why? Requesting an object fails with "Unknown Object Identifier" Why? Why do I get "noSuchName" when asking for "sysUpTime" (or similar)? Why do I sometimes get "End of MIB" when walking a tree, and sometimes not? How do I use SNMPv3? Why can't I set any variables in the MIB? Variables seem to disappear when I try to set them. Why? Why can't I change sysLocation (or sysContact)? I get an error when trying to set a negative value - why? I get an error when trying to query a string-indexed table value - why? How should I specify string-indexed table values? How do I send traps and notifications? How do I receive traps and notifications? How do I receive SNMPv1 traps? Why don't I receive incoming traps? My traphandler script doesn't work when run like this - why not? How can the agent receive traps and notifications? How big can an SNMP request (or reply) be? How can I monitor my systems (disk, memory, etc)? Applications complain about entries in your example 'snmp.conf' file. Why? OK, what should I put in snmp.conf? How do I specify IPv6 addresses in tools command line arguments? PERL What is the purpose of the Perl SNMP module? Where can I get the Perl SNMP package? How do I install the Perl SNMP modules? But compiling this fails! Why? Compiling the Perl module works OK, but 'make test' fails. Why? Why can't mib2c (or tkmib) locate SNMP.pm? Why can't mib2c (or tkmib) load SNMP.so? Why can't tkmib locate Tk.pm? Why does your RPM complain about missing Perl modules? I've got a problem with the Net-SNMP module. Can you help? MIBS Where can I find a MIB compiler? Why aren't my MIB files being read in? Where should I put my MIB files? What does "Cannot find module (XXX-MIB)" mean? I'm getting answers, but they're all numbers. Why? What does "unlinked OID" mean? The parser doesn't handle comments properly. Why not? How can I get more information about problems with MIB files? What's this about "too many imported symbols"? Do I actually need the MIB files? AGENT What MIBs are supported? What protocols are supported? How do I configure the agent? How do I remove a MIB from the agent? I've installed a new MIB file. Why can't I query it? How do I add a MIB to the agent? What's the difference between 'exec', 'sh', 'extend' and 'pass'? What's the difference between AgentX, SMUX and proxied SNMP? What is the purpose of 'dlmod'? Which should I use? Can I use AgentX when running under Windows? How can I run AgentX with a different socket address? How can I turn off SMUX support? How can I combine two copies of the 'mib2' tree from separate subagents? What traps are sent by the agent? Where are these traps sent to? How can I send a particular trap to selected destinations? When I run the agent it runs and then quits without staying around. Why? After a while the agent stops responding, and starts eating CPU time. Why? How can I stop other people getting at my agent? How can I listen on just one particular interface? The agent is complaining about 'snmpd.conf'. Where is this? Why does the agent complain about 'no access control information'? How do I configure access control? How do I configure SNMPv3 users? The 'createUser' line disappears when I start the agent. Why? What's the difference between /var/net-snmp and /usr/local/share/snmp? My new agent is ignoring the old snmpd.conf file. Why? Where should the snmpd.conf file go? Why am I getting "Connection refused"? Why can't I see values in the UCDavis 'extensible' or 'disk' trees? Why can't I see values in the UCDavis 'memory' or 'vmstat' tree? What do the CPU statistics mean - is this the load average? How do I get percentage CPU utilization using ssCpuRawIdle? What about multi-processor systems? The speed/type of my network interfaces is wrong - how can I fix it? The interface statistics for my subinterfaces are all zero - why? Does the agent support the RMON-MIB? What does "klread: bad address" mean? What does "nlist err: wombat not found" (or similar) mean? What does "Can't open /dev/kmem" mean? The system uptime (sysUpTime) returned is wrong! Can the agent run multi-threaded? Can I use AgentX (or an embedded SNMP agent) in a threaded application? COMPILING How do I control the environment used to compile the software? How do I control the environment used to compile the software under Windows? Why does the compilation complain about missing libraries? How can I reduce the memory footprint? How can I reduce the installation footprint or speed up compilation? How can I compile the project for use on an embedded system? How can I compile the project to use static linking? Why does 'make test' skip various tests? Why does 'make test' complain about a pid file? CODING How do I write C code to integrate with the agent? How does the agent fetch the value of a MIB variable from the system? Mib2c complains about a missing "mib reference" - what does this mean? Mib2c complains about not having a "valid OID" - what does this mean? Why doesn't mib2c like the MIB file I'm giving it? Mib2c ignores my MIB and generates a pair of 'mib-2' code files. Why? What's the difference between the various mib2c configuration files? Which mib2c configuration file should I use? How can I have mib2c generate code for both scalars and tables? Are there any examples, or documentation for developing MIB modules? Where should I put the files produced by 'mib2c'? Why doesn't my new MIB module report anything? Why does the iterator call my get_{first,next} routines so often? How can I get the agent to generate a trap (or inform)? How can I get an AgentX sub-agent to generate a trap (or inform)? How can I get the agent to send an SNMPv1 (or SNMPv2c) trap? How can I get the agent to include varbinds with an SNMPv1 trap? How can I get the agent to send an SNMPv1 enterprise-specific trap? How can I get the agent to send an SNMPv3 trap (or inform)? Why does calling 'send_v2trap' generate an SNMPv1 trap (or vice versa)? How can I register a MIB module in a different (SNMPv3) context? MISC What ASN.1 parser is used? What is the Official Slogan of the net-snmp-coders list? GENERAL ======= What is it? ---------- - Various tools relating to the Simple Network Management Protocol including: * An extensible agent * An SNMP library * tools to request or set information from SNMP agents * tools to generate and handle SNMP traps * a version of the unix 'netstat' command using SNMP * a graphical Perl/Tk/SNMP based mib browser This package is originally based on the Carnegie Mellon University SNMP implementation (version 2.1.2.1), but has developed significantly since then. Where can I get it? ------------------ Download: - http://www.net-snmp.org/download/ Web page: - http://www.net-snmp.org/ Sourceforge Project page: - http://www.net-snmp.org/project/ Mirrors (note that sourceforge download servers are mirrored themselves): - Greece: ftp://ftp.ntua.gr/pub/net/snmp/net-snmp/ What documentation is available? ------------------------------- This FAQ (!) README and individual READMEs for various platforms README.thread (discusses threading issues) INSTALL PORTING EXAMPLE.conf man pages for the individual tools, files and the API A guide for extending the agent Tutorials for both ucd-snmp v4 and net-snmp v5 at http://www.net-snmp.org/tutorial/ and http://www.net-snmp.org/tutorial-5/ respectively Most of this documentation (plus archives of the mailing lists) is also available on our web page: http://www.net-snmp.org/ There is also a Wiki (including a community-maintained version of this FAQ) at http://www.net-snmp.org/wiki/ Are there binaries available? ---------------------------- There are binaries for some versions/systems available under the "net-snmp binaries" package on the SourceForge "Files" page, which is linked to from the main project download web page at http://www.net-snmp.org/download.html. These binaries are also available on the project FTP site, with a link on the same web page. What's the difference between UCD-SNMP and Net-SNMP? --------------------------------------------------- Not a great deal, really. Although the project originally started at UC Davis (hence the name), and it has always been based there, most of the contributors have had little or no connection with this institution. The move to SourceForge was intended to provide a more flexible environment for the project, and to distribute the administrative workload more evenly. The change of name simply reflects this move, which was the last remaining link with UC Davis. The 4.2.x line saw the last releases made using the ucd-snmp name, and all releases on this line have been been bug-fixes only. Release 5.0 was the first version released under the Net-SNMP name, and all further development is being done on the 5.x code base. The 4.2.x code line is now effectively closed down, as are the older 5.x branches. Much of the work done for the various 5.x releases has involved some fairly significant changes to the code - in particular the architecture of the agent. However attempts have been made to retain backwards compatibility as much as possible, and most code written for earlier releases should continue to work. The most visible change from the 4.2.x UCD suite to the 5.x Net-SNMP releases was a restructuring of the header file organisation - not least a change from to . But given the maturity of the Net-SNMP code, this should be less of a consideration for most current SNMP development projects. What operating systems does it run on? ------------------------------------- Both the applications and the agent have been reported as running (at least in part) on the following operating systems: * Linux (kernels 2.6 to 1.3) * Solaris/SPARC (11 to 2.3), Solaris/Intel (10, 9) -- see README.solaris * HP-UX (11.31 to 9.01) -- see README.hpux11 * Mac OS X (10.5 to 10.1) -- see README.osX * NetBSD (2.0 to 1.0) * FreeBSD (7.0 to 2.2) * OpenBSD (4.0 to 2.6) * BSDi (4.0.1 to 2.1) * AIX (6.1, 5.3, 5.2, 5.1, 4.3.3, 4.1.5, 3.2.5) -- see README.aix * IRIX (6.5 to 5.1) * OSF (4.0, 3.2 and Tru64 Unix 5.1B) -- see README.tru64 * SunOS 4 (4.1.4 to 4.1.2) * Ultrix (4.5 to 4.2) * Dynix/PTX 4.4 * QNX 6.2.1A We have also been informed about a port to the Stratus VOS. See http://ftp.stratus.com/vos/network/network.html for details. See the next question but one for the status of Windows support. Certain systems fail to compile particular portions of the agent. These can usually be persuaded to compile (at the loss of some functionality) by omitting the modules affected. See the next question for more details. Also note that the presence of a particular configuration in this list does not imply a perfect or complete implementation. This is simply what various people have reported as seeming to work. (Or more frequently, the configurations where people have reported problems that we think we've subsequently fixed!) What happens if mine isn't listed? --------------------------------- It's probably worth trying to compile it anyway. Unless your system is significantly different to the supported configurations, most of the code (library, applications and the agent infrastructure) should probably compile with little or no difficulty. The most likely source of problems will be MIB modules within the agent, as this tends to be where the most system-specific code is found. If only a few modules fail to compile, try removing them from the agent by running "configure --with-out-mib-module=xxx,yyy", and re-compiling. If a large number of modules fail, then it might be easier to start from a relatively bare system, using "configure --enable-mini-agent --with-defaults". Then if this minimal agent compiles and runs successfully, try adding each of the missing mibgroups individually using the configure option '--with-mib-module'. If configure fails with "invalid configuration" messages, or you get completely stuck, contact the coders list for advice. Similarly, if you manage to get this working on a new system, please let us know of any code changes that you needed to make, together with details of the hardware you're using, and what versions of the operating system you've tried it on. The entry 'host' in the file 'config.status' should show this information. Oh, and congratulations! Does it run on Windows? ---------------------- The suite should compile and run on Win32 platforms, including the library, command-line tools and the basic agent framework. Note that the agent now includes support for the MIB-II module, but this requires Microsoft's Core Platform SDK. Instructions for how to install this are given in README.win32. Pre-compiled binaries are available from the project web site. As of v5.4, the Net-SNMP agent is able to load the Windows SNMP service extension DLLs by using the Net-SNMP winExtDLL extension. Some other Net-SNMP MIB modules, including the UCD pass-through extensions, do not currently work under Windows. Volunteers to assist with these missing modules are likely to welcomed with open arms :-) Further details of Windows support (currently Visual C++, MinGW and Cygnus cygwin32) is available in the file README.win32. How do I find out about new releases? ------------------------------------ There is a mailing list for these announcements net-snmp-announce@lists.sourceforge.net To be added to (or removed from) this list, visit http://www.net-snmp.org/lists/net-snmp-announce/ Or you can send a message to the address net-snmp-announce-request@lists.sourceforge.net with a subject line of 'subscribe' (or 'unsubscribe' as appropriate). Advance notice of upcoming releases are also made on the net-snmp-users list (for "release candidates") for a week or two before the full release, and on the net-snmp-coders list (for "pre-releases") during the period prior to this. Major code revisions may be announced more widely, but these lists are the most reliable way to keep in touch with the status of the package. Patches to fix known problems are also made available via the web site: http://www.net-snmp.org/patches/ How can I find out what other people are doing? ---------------------------------------------- There is a general purpose discussion list net-snmp-users@lists.sourceforge.net To be added to (or removed from) this list, visit http://www.net-snmp.org/lists/net-snmp-users/ Or you can send a message to the address net-snmp-users-request@lists.sourceforge.net with a subject line of 'subscribe' (or 'unsubscribe' as appropriate). To find out what the developers are doing, and to help them out, please read the PORTING file enclosed with the package. There is also a #net-snmp IRC channel set up on the freenode.net chat system. You can connect to this via chat.freenode.net. See http://www.freenode.net/ for more information on getting started with IRC. Several core developers hang out on this channel on a fairly regular basis. How do I submit a patch or bug report? ------------------------------------- The best way to submit a bug report is via the bug database through the interface found at http://www.net-snmp.org/bugs/ Be sure to include the version of the package that you've been working with, the output of the command 'uname -a', the precise configuration or command that triggers the problem and a copy of any output produced. Questions about using the package should be directed at the net-snmp-users@lists.sourceforge.net mailing list. Note that this mailing list is relatively busy, and the people answering these questions are doing so out of the goodness of their hearts, and in addition to their main employment. Please note the following: - use plain text mail, rather than HTML - don't resend questions more than once (even if no-one answered immediately) - include full details of exact commands and error messages ("I've tried everything, and it doesn't work" isn't much use!) - do *NOT* send messages to -users and -coders mailing lists (most developers read both anyway) - don't mail the developers privately - keep everything on the list We can't promise to be able to solve all problems, but we'll certainly try and help. But remember that this is basically an unsupported package. It's Open Source, so if you need something fixing badly enough, fundamentally it's up to you to do the work. All patches should be submitted to the patch manager at http://www.net-snmp.org/patches/ If possible, submit a bug report describing the patch as well (referencing it by its patch number) since the patch manager doesn't contain a decent description field. The best way to submit patch (diff) information is by checking out the current code from the development git trunk, making your changes and then running "git diff" or "git format-patch" after you're done. (Please see http://www.net-snmp.org/wiki/index.php/Git for further information on using git with the Net-SNMP project) If you're working from a source code distribution, and comparing old and new versions of a code file, use "diff -u OLDFILE NEWFILE" Can I reuse the code in my commercial application? ------------------------------------------------- The details of the COPYRIGHTs on the package can be found in the COPYING file. You should have your lawyer read this file if you wish to use the code in your commercial application. We will not summarize here what is in the file, as we're not lawyers and are unqualified to do so. What's the difference between SNMPv1, SNMPv2 and SNMPv3? ------------------------------------------------------- What's the difference between SNMPv2 and SNMPv2c? ------------------------------------------------ A full description is probably beyond the scope of this FAQ. Very briefly, the original protocol and admin framework was described in RFCs 1155-1157, and is now known as SNMPv1. Practical experience showed up various problems and deficiencies with this, and a number of revised frameworks were developed to try and address these problems. Unfortunately, it proved difficult to achieve any sort of agreement - particularly over the details of the administrative framework to use. There was less disagreement over the proposed changes to the protocol operations. These included: * increasing the range of errors that could be reported * introducing "exception values" (so a single missing value didn't affect the other varbinds in the same request) * a new GETBULK operation (a supercharged GETNEXT) * new notification PDUs (closer in structure to the other request PDUs) Strictly speaking, it's this revised protocol (originally defined in RFC 1905, and most recently in RFC 3416) that is "SNMPv2". The only framework based on this protocol that saw a significant level of use was "Community-based SNMPv2" or "SNMPv2c" (defined in RFC 1901). This retained the same administrative framework as SNMPv1 (with all of the accompanying limitations), but using the new protocol operations. More recently, a new administrative framework has been developed, building on the various competing SNMPv2 proposals, and using the same SNMPv2 protocol operations. This is SNMPv3, which is defined in RFCs 3411-3418. It addresses some of the deficiencies of the community-based versions, including significant improvements to the security of SNMP requests (like it finally has some!). SNMPv3 is now a full IETF standard protocol. Strictly speaking, SNMPv3 just defines a fairly abstract framework, based around the idea of "Security Models" and "Access Control Models". It's this combination of SNMPv3 plus accompanying models that actually provides a working SNMP system. However, the only models in common use are the "User-based Security Model" (RFC 3414) and the "View-based Access Control Model" (RFC 3415). So "SNMPv3" is frequently used to mean the combination of the basic SNMPv3 framework with these two particular models. This is also sometimes described as "SNMPv3/USM". So in brief: - SNMPv2c updated the protocol operations but left the administrative framework unchanged. - SNMPv3 updated the administrative framework but left the protocol operations unchanged. Which versions of SNMP are supported in this package? ---------------------------------------------------- This package currently supports the original SNMPv1 (RFC 1157), Community-based SNMPv2 (RFCs 1901-1908), and SNMPv3 (RFCs 3411-3418). The agent will respond to requests using any of these protocols, and all the tools take a command-line option to determine which version to use. Support for SNMPv2 classic (a.k.a. "SNMPv2 historic" - RFCs 1441-1452) was dropped with the 4.0 release of the UCD-snmp package. Can I use SNMPv1 requests with an SNMPv2 MIB (or vice versa)? ------------------------------------------------------------ Yes. The syntax used to specify a MIB file (better referred to as SMIv1 or SMIv2) is purely concerned with how to define the characteristics of various management objects. This is (almost) completely unrelated to the versions of the protocol used to operate on these values. So it is quite reasonable to use SNMPv1 requests on objects defined using SMIv2, or SNMPv2 (or SNMPv3) requests on objects defined using SMIv1. The one exception is objects of syntax Counter64, which are only accessible using SNMPv2 or higher. SNMPv1 requests will either treat such objects as an error, or skip them completely. Note that SMIv1 is effectively obsolete, and all new MIBs should be written using SMIv2. How can I monitor my system with SNMP? ------------------------------------- There are two main methods of using SNMP for monitoring. One is to regularly query the SNMP agent for information of interest, graphing these values and/or saving them for later analysis. That's not really the focus of the Net-SNMP project - our tools are more low-level, single-shot commands. For this sort of high-level management, you're really looking at a management console application (such as Nagios or OpenNMS), or a data logging application (such as RRDtool, or one of its front-ends - MRTG, Cacti, etc). The other approach is to configure the SNMP agent to monitor the relevant information itself, and issue an alert when the values pass suitable limits. See the section ACTIVE MONITORING in the snmpd.conf(5) man page for details. Note that this entry makes no reference as to _what_ you should monitor, or what values might be significant. That's because it is impossible to provide a universal answer to these questions. The information to monitor, and the normal operating values will ultimately depend on your local environment. SNMP is simply a tool to _help_ you manage your systems - it isn't a magic panacea - you still have to think for yourself! Where can I find more information about network management? ---------------------------------------------------------- There are a number of sites with network management information on the World Wide Web. Some of the most useful are http://www.simpleweb.org/ http://www.snmplink.org/ http://www.mibdepot.com/ The SNMP Usenet newsgroup is now mostly defunct, but although the FAQ hasn't been updated for a while, it still contains a large amount of useful information relating to SNMP, including books, software, other sites, how to get an enterprise number, etc, etc. This is available from ftp://rtfm.mit.edu/pub/usenet/comp.protocols.snmp/ or via any of the Web sites above. What ports does SNMP use? ------------------------ There are three main network ports (and one named socket), which are typically used by SNMP. These are: - UDP port 161 - SNMP requests (GET* and SET) - UDP port 162 - SNMP notifications (Traps/Informs) - TCP port 705 - AgentX - /var/agentx/master - AgentX However, these are simply the default "well-known" ports for these purposes, and it is perfectly possible to accept requests on other ports. Is Net-SNMP thread safe? ----------------------- Strictly speaking, no. However, it is possible to use the library within a multi-threaded management application. This is covered in detail in the file README.thread (shipped with the standard distribution), but can be summarised as follows: - Call 'snmp_sess_init()' prior to activating any threads. This reads in and parses MIB information (which isn't thread-safe) as well as preparing a session structure for subsequent use. - Open an SNMP session using 'snmp_sess_open()' which returns an opaque session handle, which is essentially independent of any other sessions (regardless of thread). - Resource locking is not handled within the library, and is the responsibility of the main application. The Net-SNMP agent has not been designed for multi-threaded use. It should be safe to use the agent library to embed a subagent within a threaded application as long as *all* SNMP-related activity (including generating traps, and parsing MIBs) is handled within a single thread. The command-line tools shipped as part of the Net-SNMP distribution are simple single-threaded applications, and are not designed for multi-threaded use. Adapting these to a threaded model is left as an exercise for the student. The same holds true for the notification receiver (snmptrapd). Unfortunately, the SNMPv3 support was added about the same time as the thread support and since they occurred in parallel the SNMPv3 support was never checked for multi-threading correctness. It is most likely that it is not thread-safe at this time. APPLICATIONS ============ How do I add a MIB? ------------------ This is actually two separate questions, depending on whether you are referring to the tools, or the agent (or both). See the next question or the next section respectively. How do I add a MIB to the tools? ------------------------------- Adding a MIB to the client-side tools has two main effects: - it allows you to refer to MIB objects by name (rather than having to use the numeric OIDs) - it allows the results to be displayed in a more immediately meaningful fashion. Not just giving the object names, but also showing named enumeration values, and interpreting table indexes properly (particularly for string and OID index values). There are two steps required to add a new MIB file to the tools. Firstly, copy the MIB file into the appropriate location: cp MY-MIB.txt /usr/local/share/snmp/mibs (which makes it available to everyone on the system) or mkdir $HOME/.snmp mkdir $HOME/.snmp/mibs cp MY-MIB.txt $HOME/.snmp/mibs (which makes it available to you only) Note that the location of the shared MIB directory may be different from that given here - see the FAQ entry "Where should I put my MIB files?" for more information. Secondly, tell the tools to load this MIB: snmpwalk -m +MY-MIB ..... (load it for this command only) or export MIBS=+MY-MIB (load it for this session only) or echo "mibs +MY-MIB" >> $HOME/.snmp/snmp.conf (load it every time) Note that the value for this variable is the name of the MIB module, *not* the name of the MIB file. These are typically the same (apart from the .txt suffix), but if in doubt, check the contents of the file. The value to use is the token immediately before the word DEFINITIONS at the start of the file. Or use the special value "all" to have the tools load all available MIBs (which may slow them down, particularly if you have a large number of MIB files. Note that you need *both* steps. Adding a MIB in this way does *not* mean that the agent will automatically return values from this MIB. The agent needs to be explicitly extended to support the new MIB objects, which typically involves writing new code. See the AGENT section for details. Most of the tools (apart from 'snmptable') will work quite happily without any MIB files at all - although the results won't be displayed in quite the same way. Similarly, the agent doesn't need MIB files either (other than to handle MIB object names in the configuration file). Why can't I see anything from the agent? --------------------------------------- Fundamentally, there are two basic reasons why a request may go unanswered. Either the management application does not like the request (so never sends it), or the agent does not like the request (so never responds). The simplest way to distinguish between the two is to run the command with the command-line option '-d'. If this doesn't display a hex dump of the raw outgoing packet, then it's the client side which is dropping the request. Hopefully you should also see an error message, to help identify what's wrong. If this displays one or more outgoing dumps (but nothing coming back), then the request is failing at the agent end. See the next entry for more details. There are three further possibilities to consider: One is that the agent may return a response to the original query, but the management application may not like this response, and refuse to display it. This is relatively unusual, and typically indicates a flaw with the remote agent. (I hope you're not contemplating the suggestion that the Net-SNMP command-line tools might contain bugs!) The typical symptoms of this would be that the '-d' option would display a sequence of sending and received packet dumps, with the same contents each time. Ask on the mailing list for advice. Alternatively, the agent may simply not support the MIB objects being requested. This is most commonly seen when using the "snmpwalk" tool (particularly with SNMPv1). The symptoms here would be that '-d' would show two pairs of raw packet dumps - one a GETNEXT request (A1 in the sending packet), followed by a GET request (A0). Repeating the same request with the "snmpgetnext" command-line tool should show the information (if any) that the agent returned, which was then discarded by snmpwalk as irrelevant. Note that this is how snmpwalk was designed to work. It is not an error. Finally, it may be that the agent is simply taking too long to respond. The easiest way to test for this is to add the command-line options "-t 60 -r 0", which will send a single request (with no repetitions) and wait for a minute before giving up. This ought to be long enough for all but the most-overloaded agent, or inefficient MIB module! If this turns out to be the cause, then ask on the mailing list for advice on options for improving the performance. Why doesn't the agent respond? ----------------------------- Assuming that the tests outlined in the previous entry indicate that the problem lies with the agent not responding, the obvious question is "why not". Again, there are two basic possibilities - either the agent never sees the request, or it receives it but is unwilling (or unable) to process it. If the remote system is running the Net-SNMP agent, then the easiest way to distinguish between these two cases is to shut down the agent, and re-start it manually using the options -f -Le -d Then send the same query as before. This should display raw dumps of packets seen (or sent) by the agent, just as with the client side in the previous entry. If the agent does not display anything, then it is simply not receiving the requests. This may be because they are being blocked by network or local firewall settings ('iptables -L'), or the agent may not be listening on the expected interfaces ('netstat -a'). This is most commonly encountered when running queries from a remote host, particularly if the same request succeeds when run on the same system as the agent itself. If the agent displays a dump of the incoming request, but nothing going out, then the most likely cause is access control settings. See the relevant entries in the AGENT section for details. Note that if the agent receives an SNMPv1 or SNMPv2c request with a unknown community string, then it will not return an error response - the request is simply discarded. Another possibility is that the request may be rejected by settings in /etc/hosts.{allow,deny}. Again, '-d' will display an incoming packet dump but no corresponding outgoing response. However in this situation, the agent should also log a message that the request is being refused. Running the agent with '-d' can also help identify situations where the agent *is* responding to the request, but only after a long delay. This would be indicated by a series of incoming packet dumps (showing various retries from the client side), followed by several outgoing dumps - possibly long after the client tool has given up in disgust. See the entry The agent worked for a while, then stopped responding. Why? later in this section. I can see the system group, but nothing else. Why? -------------------------------------------------- This is almost definitely due to the access configuration of the agent. Many pre-configured systems (such as most Linux distributions) will only allow access to the system group by default, and need to be configured to enable more general access. The easiest way to test this is to try a GETNEXT request on one of the other standard groups e.g. snmpgetnext ..... interfaces If the agent responds with "hrSystemUptime.0" or "end of MIB", then it is clearly configured in this way. See the entries on access control in the AGENT section for more information. Why can't I see values in the tree? ----------------------------------------------- If you can see most of the standard information (not just the system and hrSystem groups), but not in the vendor-specific 'enterprises' tree, then once again there are several possible causes. Firstly, it's possible that the agent does not implement this particular enterprise tree. Remember that adding a MIB to the client tools does *not* automatically add support for these object to the agent. See the AGENT section for more information. Alternatively, it may be that the agent does implement some or all of this enterprise tree, but the access control settings are configured to block access to it. The simplest way to checks whether the agent implements a given portion of the OID tree is to run snmpwalk .... nsModuleName and look for index values that fall in the area of interest. (Always assuming that you have access to this particular section of the Net-SNMP enterprise tree, of course!) Checking the access control settings can be done by examining the tables vacmAccessTable and vacmViewTreeFamilyTable. Note that these are used to configure access control for *all* versions of SNMP - not just SNMPv3. The third possibility is that simply isn't any information in the specified tree. For example, several of the tables in the UCDavis enterprise tree (such as prTable, extTable, dskTable and fileTable) require explicit configuration in the snmpd.conf file. If you query this particular tables without the necessary configuration entries, then they will be empty. Finally, if you can't see anything from *any* enterprise-specific tree, then this may be down to how you are asking for the information. By default, if "snmpwalk" is run without an explicitly starting OID, then it will display the contents of the 'mib-2' tree, containing most of the IETF-standard management information supported by the agent. When the agent reaches the end of this tree, it will return the first enterprise-specific value, 'snmpwalk' will recognise that this marks the end of the (implicit) requested tree, and stop. No enterprise-specific information will be displayed. To walk the whole tree, and see *all* the information that the agent supports, specify a starting point of '.iso' or '.1'. To walk a specific enterprise subtree, specify the root of this tree as the starting point - e.g: snmpwalk -v1 -c public localhost UCD-SNMP-MIB::ucdavis There is more information about particular UCD-specific subtrees in the AGENT section. The agent worked for a while, then stopped responding. Why? ----------------------------------------------------------- There are three basic possibilities: - the agent has crashed - it is hanging - it is temporarily overloaded Detecting whether the agent has crashed should be fairly straighforward. If you can reliably reproduce this crash (e.g. by sending a particular SNMP request), then contact the coders list for advice. It's the other two cases that are probably more significant. To tell the difference between these two, try leaving the agent undisturbed for a while, and then probe it using a single 'snmpget' request, specifying a longer timeout (e.g. '-t 120'). If it now responds, then something was probably sending requests (including duplicate retries) faster than the agent could process them, and it was building up a backlog. Try adjusting the timeout period and retry frequency of these client requests, or look at improving the efficiency of the implementation of the relevant MIB objects. If the agent remains unresponsive (particularly if the load on the system is steadily climbing), then it's probably hanging, and all you can really do is restart the agent. If you can identify what causes this to happen, then contact the coders list for advice. Requesting an object fails with "Unknown Object Identifier" Why? ---------------------------------------------------------------- If a general snmpwalk shows a particular entry, but asking for it more specifically gives a "sub-identifier not found:" or "Unknown Object Identifier" error, then that's a problem with the tool, rather than the agent. Firstly, make sure that you're asking for the object by the right name. Object descriptors are case-sensitive, so asking for 'sysuptime' will not be recognised, but 'sysUpTime' will. Alternatively, the object may be defined in a MIB that hasn't been loaded. Try loading in all the MIB files: snmpget -m ALL -v1 -c public localhost sysUpTime.0 or specify the name of the appropriate MIB explicitly: snmpget -v1 -c public myhost SNMPv2-MIB::sysUpTime.0 Note that this uses the name of the *module*, not the name of the file. However, if 'snmpwalk' displays the object by name, this is unlikely to be the cause, and you should look closely at the exact object name you are using. In particular, see the next entry. Why do I get "noSuchName" when asking for "sysUpTime" (or similar)? ------------------------------------------------------------------ Assuming that you do have access to this object, the most likely cause is forgetting the instance subidentifier. If you try walking the 'system' group (or any other part of the MIB tree), you should notice that all of the results have a number after the object name. This is the "instance subidentifier" of that particular MIB instance. For values in tables (such as the sysORTable), this acts as an index into the table - a very familiar concept. But *all* SNMP values will display an instance number, whether or not they are part of a table. For non-table objects ("scalars"), this instance subidentifier will always be '0', and it *must* be included when making a GET request. Compare the following: $ snmpget -v1 -c public localhost sysUpTime Error in packet Reason: (noSuchName) There is no such variable name in this MIB. This name doesn't exist: system.sysUpTime $ snmpget -v1 -c public localhost sysUpTime.0 system.sysUpTime.0 = Timeticks: (69189271) 8 days, 0:11:32.71 This is a little less obscure when using SNMPv2c or v3 requests: $ snmpget -v 2c -c public localhost sysUpTime system.sysUpTime = No Such Instance currently exists Why do I sometimes get "End of MIB" when walking a tree, and sometimes not? -------------------------------------------------------------------------- This depends on which MIB modules are supported by the agent you are querying and exactly what you're asking for. Note that a tree is walked by repeatedly asking for "the next entry" until all the values under that tree have been retrieved. However, the agent has no idea that this is what's happening - all it sees is a request for "the next entry after X". If the object X happens to be the last entry in a sub-tree, the agent will provide the next object supported (as requested) even though this will be in a different subtree. It's up to the querying tool to recognise that this last result lies outside the area of interest, and simply discard it. If the object X happens to be the last entry supported by the agent, it doesn't have another object to provide, so returns an "end of MIB" indication. The Net-SNMP tools report this with the message above. But in either case, the actual information provided will be the same. How do I use SNMPv3? ------------------- The simplest form of SNMPv3 request is unauthenticated and unencrypted (noAuthNoPriv). It simply requires a user name, and would look something like: snmpget -v 3 -l noAuthNoPriv -u dave localhost sysUpTime.0 However this approach foregoes the security protection which is the main advantage of using SNMPv3 (and the agent must also be explicitly configured to allow unauthenticated requests from that user). The most common form of SNMPv3 request is authenticated but not encrypted (authNoPriv). This specifies the pass phrase to authenticate with: snmpget -v 3 -l authNoPriv -u dave -A "Open the Door" localhost sysUpTime.0 A fully secure (i.e. encrypted) request (authPriv) would also specify the privacy pass phrase: snmpget -v 3 -l authPriv -u dave -A "Open the Door" -X "Bet you can't see me" localhost sysUpTime.0 In practise, most of these would probably be set via configuration directives in a personal $HOME/.snmp/snmp.conf file (note, *not* the agent's snmpd.conf file). The equivalent settings for the third example would be: defSecurityName dave defSecurityLevel authPriv defAuthPassphrase "Open the Door" defPrivPassphrase "Bet you can't see me" If the AuthPassphrase and the PrivPassphrase are the same, then you can use the single setting defPassphrase "Open the Door and see me" instead. See the AGENT section for how to configure the agent for SNMPv3 access. Why can't I set any variables in the MIB? ---------------------------------------- There are three possible reasons for this: Many MIB objects are defined as "read-only" and inherently cannot be changed via SET requests. Attempts to do so will typically be rejected by the 'snmpset' command without ever being sent to the agent. Of those objects that can in principle be changed, the agent may not include the code necessary to support SET requests. (GET and GETNEXT are much easier to handle - particularly for objects relating to the internals of the underlying operating system). Even if SET support has been implemented, the agent may not be configured to allow write access to this object. Ready-installed distributions (such as those shipped with Linux) tend to be configured with read-only access to part of the mib tree (typically just the system group) and no write access at all. To change this, you will need to set up the agent's access control configuration. See the AGENT section for more details. Note that neither the community string "public" nor "private" can be used to set variables in a typical default configuration. Variables seem to disappear when I try to set them. Why? -------------------------------------------------------- This is actually the same as the previous question - it just isn't particularly obvious, particularly when using SNMPv1. A typical example of this effect would be $ snmpget -v1 -c public localhost sysLocation.0 sysLocation.0 = somewhere nearby $ snmpset -v1 -c public localhost sysLocation.0 s "right here" Error in packet. Reason: (noSuchName) There is no such variable name in this MIB. This name doesn't exist: sysLocation.0 Trying the same request using SNMPv2 or above is somewhat more informative: $ snmpset -v 2c -c public localhost sysLocation.0 s "right here" Error in packet. Reason: notWritable The SNMPv1 error 'noSuchName' actually means: "You can't do that to this variable" rather than "this variable doesn't exist". It may be the case that it doesn't exist at all. It may exist but you don't have access to it (although different administrative credentials might be accepted). Or it may exist, but you simply can't perform that particular operation (e.g. changing it). Similarly, the SNMPv2 error 'notWritable' means "not writable in this particular case" rather than "not writable under any circumstances". If you are sure that the object is both defined as writable, and has been implemented as such, then you probably need to look at the agent access control. See the AGENT section for more details. But see the next entry first. Why can't I change sysLocation (or sysContact)? ---------------------------------------------- There is one final possibility to consider for why a SET request might be rejected. The values for certain MIB objects (including 'sysLocation' and 'sysContact') can be configured via the snmpd.conf file. If this is done, then these particular objects become read-only, and cannot be updated via SET commands, even if the access control settings would otherwise allow it. This may seem perverse, but there is good reason for it. If there is a configuration setting for one of these objects, then that value will be used whenever the agent re-starts. If the object was allowed to be updated using SET, this new value would be forgotten the next time the agent was re-started. Hence the Net-SNMP agent rejects such requests if there's a value configured via the 'snmpd.conf' file. If there isn't such a config setting, then the write request will succeed (assuming suitable access control settings), and the new value will be retained the next time the agent restarts. I get an error when trying to set a negative value - why? -------------------------------------------------------- This is a different problem. What's happening here is that the routine that parses the arguments to the 'snmpset' command is seeing the '-' of the new value, and treating it as a command-line option. This normally generates an error (since digits typically aren't valid command line options). The easiest way to solve this is include the "end-of-option" indicator '--' in the command line, somewhere before the new value (but after all of the options, obviously). For example: snmpset -v 2c -c public localhost -- versionRestartAgent.0 i -1 (This command will still fail, since -1 isn't an acceptable value for this particular object, but that's not the point here!) I get an error when trying to query a string-indexed table value - why? ---------------------------------------------------------------------- The Net-SNMP library will normally try to interpret string-based index values, and display them in a meaningful manner: $ snmpgetnext .... vacmGroupName vacmGroupName.3."dave" = theWorkers The command-line tools will also accept string-valued indexes within an OID, and convert them into the appropriate numeric form before sending an SNMP request. However the Unix shell will typically swallow the quotes around the string index value, before the SNMP tools can get a chance to interpret them. The answer is to escape the quotes, to protect them from the shell, and allow them to be passed through to the OID parser: snmpget .... vacmGroupName.3.\"dave\" or snmpget .... 'vacmGroupName.3."dave"' Another alternative is to avoid trying to specify the index value as a string, and provide the numeric subidentifiers directly: snmpget .... vacmGroupName.3.4.100.97.118.101 (where '3' indicates SNMPv3, '4' is the length of the string index, followed by the ASCII values of the individual characters). The command-line option '-Ob' will display the results of querying a string-indexed table in this format: $ snmpgetnext -Ob .... vacmGroupName vacmGroupName.3.4.100.97.118.101 = theWorkers How should I specify string-indexed table values? ------------------------------------------------ There's one other aspect of string-indexed tables that can cause problems - the difference between implicit- and explicit-length strings, and how to represent these when making an SNMP query. The most common style of string index uses an explicit length, followed by the individual ASCII character values: "dave" = 4.'d'.'a'.'v'.'e' (as shown in the previous entry). However if the string index is defined in the MIB file as IMPLIED (or if it has a fixed length, such as a physical ethernet address), then the length subidentifier is omitted, and the index simply consists of the character values: "dave" = 'd'.'a'.'v'.'e' Note that IMPLIED index objects can only appear as the *last* index for a table. The Net-SNMP library uses double quotes (i.e. "dave) to indicate an explicit length string index value, and single quotes (i.e. 'dave') to indicate an implicit length one. If you use the wrong style of quotes, then the resulting OID will be incorrect, and you'll get confusing results to your query. How do I send traps and notifications? --------------------------------------- Traps and notifications can be sent using the command 'snmptrap'. The following examples generate the generic trap 'warmStart(1)' and a (dummy) enterprise specific trap '99' respectively: snmptrap -v 1 -c public localhost "" "" 1 0 "" snmptrap -v 1 -c public localhost "" "" 6 99 "" The empty parameters "" will use suitable defaults for the relevant values (enterprise OID, address of sender and current sysUptime). An SNMPv2 or SNMPv3 notification (either trap or inform) takes the OID of the trap to send: snmptrap -v 2c -c public localhost "" UCD-SNMP-MIB::ucdStart snmptrap -v 2c -c public localhost "" .1.3.6.1.4.1.2021.251.1 (These two are equivalent ways of specifying the same trap). Again, the empty parameter "" will use a suitable default for the relevant value (sysUptime). Any of these commands can be followed by one or more varbinds, using the same (OID/type/value) syntax as for 'snmpset': snmptrap -v 2c -c public localhost "" ucdStart sysContact.0 s "Dave" Generating traps from within the agent, or other applications, is covered in the AGENT and CODING sections. You should also read the snmptrap tutorial at http://www.net-snmp.org/wiki/index.php/TUT:snmptrap which will help you understand everything you need to know about traps. How do I receive traps and notifications? ---------------------------------------- Handling incoming traps is the job of a "notification receiver". The Net-SNMP suite include the tool 'snmptrapd' to act in this role. This can log traps to a file or via the syslog mechanism, forward them to another notification receiver and/or invoke a specified command whenever a particular notification is received. Logging notifications would be done by starting snmptrapd as: snmptrapd -Ls 7 (log to syslog using 'LOCAL7') or snmptrapd -f -Lo (log to standard output) Invoking a command to process a received notification uses one or more 'traphandle' directives in the configuration file 'snmptrapd.conf'. A typical configuration might look something like: traphandle .1.3.6.1.6.3.1.5.1 /path/to/page_me up traphandle .1.3.6.1.4.1.2021.251.1 /path/to/page_me up traphandle .1.3.6.1.4.1.2021.251.2 /path/to/page_me down traphandle default /path/to/log_it where 'page_me' and 'log_it' are the commands to be run. Forwarding notifications to another receiver would be done using similar 'snmptrapd.conf' directives: forward .1.3.6.1.4.1.8072.4.0.3 10.0.0.1 forward default 10.0.0.2 There's a tutorial with more details on the web site at http://www.net-snmp.org/wiki/index.php/TUT:snmptrap How do I receive SNMPv1 traps? ----------------------------- Directives in the 'snmptrapd.conf' file use the (SNMPv2) snmpTrapOID value to identify individual notifications. This applies to *all* versions of SNMP - including SNMPv1 traps. See the co-existence spec (RFC 2576) for details of mapping SNMPv1 traps to SNMPv2 OIDs. Note that the first traphandle directive in the previous entry uses the OID corresponding to the SNMPv1 'coldStart' trap. Why don't I receive incoming traps? ---------------------------------- Starting with net-snmp 5.3, snmptrapd will no longer automatically accept all incoming traps. It must be configured with authorized SNMPv1/v2c community strings and/or SNMPv3 users. Non-authorized traps/informs will be dropped. Please refer to the snmptrapd.conf(5) manual page for details. My traphandler script doesn't work when run like this - why not? --------------------------------------------------------------- If a traphandler script works fine when run manually from the command line, but fails or generates an error when triggered by an incoming notification, then there are two likely causes. Firstly, the interactive shell environment may not be precisely the same as that for programs executed by the snmptrapd daemon. In particular, it's quite possible that the PATH environmental variable may not include all the additional directories that are commonly set up for a personal login configuration. To avoid this problem (particularly for traphandler shell scripts), it's worth giving the full path to all programs used within the script. Secondly, the snmptrapd daemon may not always recognise the appropriate interpreter to use for a particular trap handler. If this is the case, then you can specify this interpreter explicitly as part of the trap handle directive: traphandle default /usr/bin/perl /usr/local/bin/log_it In this case, it's almost certain that you'll also need to give the full path to the traphandle script (as shown) How can the agent receive traps and notifications? ------------------------------------------------- It can't. The primary purpose of an SNMP agent is to handle requests for information from management applications. In SNMP terminology, it acts as a "command responder". It may also issue traps to report significant events or conditions ("notification generator"). But responding to such notifications is a significantly different role, and this is handled by a separate application ('snmptrapd'). Note that it is perfectly possible (even normal) for both agent and trap receiver to run on the same host. How big can an SNMP request (or reply) be? ----------------------------------------- The protocol definition specifies a "minimum maximum" packet size (484 bytes for UDP), which all systems must support, but does not attempt to define an upper bound for this maximum size. This is left to each individual implementation. The UCD software used a fixed size buffer of 1472 bytes to hold the encoded packet, so all requests and responses had to fit within this. The Net-SNMP releases handle packet buffers rather differently, and are not subject to the same fixed restrictions. How can I monitor my systems (disk, memory, etc)? ------------------------------------------------ In general, the Net-SNMP suite consists of relatively low-level tools, and there is nothing included that is designed for high-level, long-term monitoring of trends in network traffic, disk or memory usage, etc. There are a number of packages available that are designed for this purpose. Two of the most widely used are MRTG (http://www.mrtg.org/) and RRDtool (http://oss.oetiker.ch/rrdtool/). There are also several frontends built on top of RRDtool, including Cacti (http://www.cacti.net/) and Cricket (http://cricket.sourceforge.net/). There are details of how to set up Cricket to monitor some of the UCD extensions at http://www.afn.org/~jam/software/cricket/ We have also set up a page that describes in detail how MRTG can be set up to monitor disk, memory and cpu activity at http://www.net-snmp.org/tutorial-5/mrtg/index.html There is also a web-based network configuration system "Net-Policy", based upon SNMP. This is not strictly connected to the Net-SNMP project, but a number of the core developers are also involved with that system. See http://net-policy.sourceforge.net for more details. Applications complain about entries in your example 'snmp.conf' file. Why? -------------------------------------------------------------------------- There *is* no example 'snmp.conf' shipped with the standard distribution. The configuration file 'EXAMPLE.conf' is designed as a config for the agent, and should be installed as 'snmpd.conf' (note the 'd'). The file 'snmp.conf' is intended for general configuration options, applicable to all applications (via the SNMP library). Rename (or merge) the 'snmp.conf' file to 'snmpd.conf', and this should fix the problem. See the AGENT section or the 'snmpd.conf(5)' man page for more information about what should go in this file. OK, what should I put in snmp.conf? ---------------------------------- This is used to set common configuration values for most of the applications, to avoid having to specify them every time. Examples are the SNMPv3 settings mentioned above, defaults for which MIBs to load and where from (see the second entry in this section), and the default SNMP version, port and (if appropriate) community string to use. Some of these (such as MIB information), might be best put in a shared snmp.conf file (typically /usr/local/share/snmp/snmp.conf or /etc/snmp/snmp.conf) to apply to all users of the system. Others (particularly the SNMPv3 security settings), are more likely to refer to a particular user, and should probably go in a personal snmp.conf file (typically $HOME/.snmp/snmp.conf). See 'snmpget -H' and/or the snmp.conf(5) man page for more details. You can also use the "snmpconf" command to help you generate your snmp.conf configuration file (just run it and answer its questions). How do I specify IPv6 addresses in tools command line arguments? --------------------------------------------------------------- IPv6 addresses pose a particular problem for the Net-SNMP command line tools, which parse host names into pieces. In particular, normally if you specify a simple host name, it assumes you want UDP in IPv4 on port 161. By default, these two commands are actually the same: snmpget 127.0.0.1 sysUpTime.0 snmpget udp:127.0.0.1:161 sysUpTime.0 However, for IPv6 this causes a problem because IPv6 addresses also use a colon to separate addressing parts. Thus you need to enclose the address in square brackets ( [ and ] ). Because most shells use these brackets too, you also likely need to quote it: snmpget 'udp6:[::1]:161' sysUpTime.0 PERL ==== What is the purpose of the Perl SNMP module? ------------------------------------------- Short, comprehensive (but ultimately unhelpful) anwer - to provide a perl interface for SNMP operations. Longer, incomplete (but more useful) answer - there are probably two main uses for the Perl SNMP module. The first is for developing client management applications, using perl to send SNMP requests, and manipulating or displaying the results. As such, this is a straight alternative to various other SNMP toolkits currently available (for both perl and other programming languages). The second is as a means for extending the functionality of the Net-SNMP agent, by implementing new MIB modules. This is an alternative to the other script-based extension mechanisms, but is more tightly bound to the Net-SNMP agent (and hence more efficient), while still avoiding the need to write C code. It is also possible to use the perl SNMP module in the snmpd.conf file, or to process incoming notifications, but the above are probably the two primary uses. Where can I get the Perl SNMP package? ------------------------------------- Joe Marzot's excellent Perl 'SNMP' module, is included in the Net-SNMP source releases. It can be found located in the perl/SNMP subdirectory of the source tree. This is accompanied by a number of Perl modules grouped together under the NetSNMP namespace. The basic SNMP module (though not the NetSNMP additions), can also be found at any Comprehensive Perl Archive Network (CPAN) mirror site, under modules/by-module/SNMP. To find the CPAN site nearest you, please see http://www.cpan.org/SITES.html. These Perl modules need to be used in conjunction with a compatible version of the Net-SNMP library. Consult the README file in the SNMP Perl distribution to find out which version of the library it needs. How do I install the Perl SNMP modules? -------------------------------------- Assuming you have a reasonably new (and properly configured) Perl system, this should be simply: cd perl perl Makefile.PL (press RETURN when prompted for host and community) make make test make install (probably as root) It might be possible to install the basic module using perl -MCPAN -e shell ; "install SNMP" but this has not been reliably tested, and very much relies on having the correct version of the Net-SNMP library. There may also be appropriate pre-compiled versions of the Perl modules available from the Net-SNMP project website, or your O/S vendor. But compiling this fails! Why? ----------------------------- The Perl module tends to delve quite deeply into the internals of the main Net-SNMP library, and so is quite sensitive to changes within the library. It's important to use the correct version of the module, that corresponds to the version of the library you have installed. If you're working with a Net-SNMP source distribution, the appropriate versions of the Perl modules are shipped as part of the source code, but you *must* have run "make install" on the main Net-SNMP distribution *first*. If you're working with a ready-installed version of the library, make sure you obtain a compatible version of the Perl module. Note that the Perl modules will be compiled using the compiler (and compiler settings) used for compiling the original perl binary, *not* those used for compiling the Net-SNMP (or UCD) library. If these are different (e.g. 'gcc' used for one and 'cc' for the other) then this may well cause problems. It's much safer to use a consistent environment for both. This issue is discussed in greater detail in the README.solaris file. Also note that the v5 Net-SNMP suite *must* be configured to provide shared libraries in order for the Perl modules to work correctly. This is not necessary with the v4 UCD-SNMP libraries. Compiling the Perl module works OK, but 'make test' fails. Why? -------------------------------------------------------------- That's difficult to answer in general. Some of the Perl tests are rather picky, so this may simply be some minor inconsistency between your precise setup, and the expectations of the test environment. Check that you are working with the Perl distribution that matches the SNMP libraries (use the 'perl/SNMP' in preference to CPAN), and that you have installed the main libraries successfully (uninstall any old versions if you're having trouble). If all this looks OK, and if most of the tests pass, then it's probably safe to run 'make install' anyway. Probably. Why can't mib2c (or tkmib) locate SNMP.pm? ----------------------------------------- That's probably because the SNMP Perl module hasn't been installed. It's not part of the standard Perl distribution, nor is it included in the default Fedora Linux installation (for example). You'll need to install it yourself. See the second entry in this section. Why can't mib2c (or tkmib) load SNMP.so? --------------------------------------- This is probably the same problem. Either the SNMP module hasn't been installed, or it's the wrong version. See the previous questions. Why can't tkmib locate Tk.pm? ---------------------------- Tk.pm is another Perl package that needs to be installed before tkmib will run. It's also available on Perl CPAN. We suggest using version "Tk800.011" or later. It can be installed by issuing the command: perl -MCPAN -e shell ; "install Tk" Why does your RPM complain about missing Perl modules? ----------------------------------------------------- This has been particularly noted on RedHat 9, complaining about the module "perl(Term::ReadKey)" - even if this is actually present (e.g. having been installed directly from CPAN). In fact, this is not specific to Perl modules - the same issue can potentially arise with other RPM dependencies. The problem is that the RPM mechanism keeps a local database of what software packages have been installed, and checks this for any other features that this RPM requires. If software is installed "manually" rather than via rpm packages, then it will not appear in this database. Attempting to install another RPM that rely on this functionality will then complain about the "missing" package, because the RPM system doesn't know that's it's actually available. The ideal solution is to *always* install software using a consistent mechanism (which may involve building RPMs locally, or looking for a suitable pre-built version). Failing this, it's possible to tell the "rpm" command to ignore such dependencies, and install the package anyway. Try: rpm -i --nodeps {package} In this situation, it's then up to you to make sure that any other necessary packages *are* actually present on the system. I've got a problem with the Net-SNMP module. Can you help? ---------------------------------------------------------- Sorry, despite the similar-sounding name, the Net-SNMP (or Net::SNMP) module is nothing to do with this package, or the NetSNMP modules. Net::SNMP is a "pure-perl" implementation of SNMP support, developed by David Town. The developers of the (C-based) Net-SNMP suite do not have any significant experience in using this particular module, and you'll probably be better off asking for help via CPAN or some other perl-related forum. MIBS ==== Where can I find a MIB compiler? ------------------------------- That depends what you mean by a "MIB compiler". There are at least two types of tool that are commonly referred to by this name. The first is a tool to check MIB files for validity. With the Net-SNMP software, this functionality is mostly integrated within the MIB parser, and hence included in all the applications. The tool 'snmptranslate' is probably the most appropriate for this purpose. Note that the parser is fairly forgiving (see 'What ASN.1 parser is used' below), so this should not be regarded as a stamp of approval. For a more rigourous validation, use a tool such as 'smilint', or the on-line interface at http://wwwsnmp.cs.utwente.nl/ietf/mibs/validate/ The second type of "MIB compiler" is one to turn a MIB specification into C code, specifically one designed to aid agent implementation. The command 'mib2c' is an example of such a tool for the Net-SNMP agent. See the CODING section for more information. Why aren't my MIB files being read in? ------------------------------------- There are two basic likely causes - either the library isn't attemping to load these particular MIB files, or it's trying to load them but can't locate them. By default, the Net-SNMP library loads a specific subset of MIB files. This list is set when the suite is first configured and compiled, and basically corresponds to the list of modules that the agent supports. (This is a simplification, but is a reasonable first approximation). In order to load additional MIB files, it is necessary to add them to this default list. See the FAQ entry "How do I add a MIB to the tools?" for more information about how to do this. Alternatively, the tools may be looking in the wrong place. The directory where the library looks for MIB files is also set when the software is first configured and compiled. If you put new MIB files in the wrong location, then the library won't be able to find them (and will complain). This problem may arise when switching from a vendor-supplied distribution to one compiled from source (or vice versa). See the next entry for more information. Where should I put my MIB files? ------------------------------- If you've compiled the package from source (or are using binaries from the project website), then you should probably put new MIB files in the directory /usr/local/share/snmp/mibs If you are using vendor-supplied binaries, then the MIB files may well be located somewhere else (e.g. /usr/share/snmp/mibs, /opt/snmp/mibs, or /etc/sma/snmp/mibs). Have a look for where existing MIB files are installed, and try adding your MIBs to the same directory. If you compiled the source yourself, but specified a different --prefix value when running configure, then the location of the MIB directory will be {prefix}/share/snmp/mibs. If you're still not sure where to put your MIB files, try running the command snmpget -Dparse-mibs 2>&1 | grep directory This will display the location(s) where the library is looking for MIB files. What does "Cannot find module (XXX-MIB)" mean? --------------------------------------------- If this error is only generated for one or two modules, then it's likely that the named modules are not being found - perhaps they're not installed in the correct location, are not readable, or the name being used is incorrect. See the previous entries and the entry "How do I add a MIB to the tools?" for more details. Note that the name reported is the name of the MIB *module*, which is not necessarily the same as the name of the file. If there are a large number of such errors, then it's more likely that either the MIB files haven't been installed at all. If you are compiling from source, then it is necessary to run "make install" in order to set up the full run-time environment. Otherwise, see the previous entry to check whether the MIBs are installed in the correct location for the tools to find them. I'm getting answers, but they're all numbers. Why? ------------------------------------------------- This is related to the previous questions. Remember, the results that you receive from an agent do not depend on which MIBs are loaded by the client tools - purely on how the agent was compiled and configured. Because the tools don't necessarily read in every MIB file they can find (and the relevant MIB file may not be available anyway), it is quite possible for results from an agent to refer to modules that have not been loaded (particularly with GETNEXT requests, or when walking a tree). The results will be reported correctly, but won't be translated to use named identifiers (or display the values in the most appropriate manner). To fix this, add the missing MIB files to the list of MIBs to be loaded. See the previous entries and the entry "How do I add a MIB to the tools?" for more information. What does "unlinked OID" mean? ----------------------------- This means that the library has been able to find the MIB module, and parse the individual objects defined in it, but is having problems linking them together into a consistent tree. In particular, it can't find an object corresponding to the name within the braces (i.e. the 'xxx' in '{xxx 99}'). This is probably due either to a typo in this name (remember that names are case sensitive, so a reference to 'xxx' will *not* match a definition of 'Xxx'), or else the name is defined in another MIB file, and this dependency is missing from the IMPORT clause of this MIB file. The parser doesn't handle comments properly. Why not? ---------------------------------------------------- The way that comments are handled in a MIB file is subtly different to the equivalent syntax in most typical programming languages, and this difference can catch out the unwary. In particular, there are two common situations which can lead to problems. The first scenario is where the MIB designer has attempted to "comment out" an unwanted line that already contains a comment: -- broken ::= { myMIB 1 } -- This isn't working yet The assumption here is that a comment continues to the end of the line. Unfortunately, this is not correct. A comment will continue either to the end of the line, *or* the next occurance of a pair of dashes. Thus in this case, the definition of "broken" is commented out (as intended) but the following text ("This isn't working yet") is treated as an active part of the MIB, and will generate an error. The second scenario is where a line of dashes has been used to mark out separate parts of a MIB file. Depending on the exact number of dashes used, this may still result in a syntactically valid MIB file, but has a 1-in-4 possibility of triggering an error. This means that this particular situation can be particularly difficult to spot! Most of the Net-SNMP applications have a command-line option (-Pc) which will work around this problem by treating the whole line as a comment. But this is not strictly legal, and the offending MIB file should really be corrected. How can I get more information about problems with MIB files? ------------------------------------------------------------ The command 'snmptranslate' is used to translate between numeric and symbolic forms of OIDs. It uses the same MIB parsing routines as the commands that actually communicate with a network management agent, but can be used standalone. As such, it is a useful tool for identifying problems with reading in MIB files. In particular, the following options may be useful in identifying problems: -Pw warns about conflicting symbols -PW prints more verbose warnings about other problems as well (in both cases, ignore the 'xmalloc' reports) -T provides sub-options for various views of these entries There are other '-P' options to control various aspects of MIB parsing. See the 'snmptranslate(1)' and 'snmpcmd(1)' man pages for more details, or the tutorial at http://www.net-snmp.org/tutorial-5/commands/snmptranslate.html For a more rigourous validation, use a tool such as 'smilint', or the on-line interface at http://wwwsnmp.cs.utwente.nl/ietf/mibs/validate/ What's this about "too many imported symbols"? --------------------------------------------- Any MIB file starts with an (optional) list of identifiers that it "imports" from other files. The parser handles this using a fixed size buffer to hold the import information. There are two circumstances in which this can result in the error message shown above. Firstly, if the MIB file refers to an unusually large number of external identifiers. Handling this case requires a (trivial) patch to the parsing code. Contact the coders list for advice. (This is extremely rare - the only example that we've come across is the Cabletron Trap MIB). Much more common is a syntax error in the IMPORTS clause of the MIB file in question. In particular, check that this section ends in a semicolon, before going on to the main MIB object definitions. Do I actually need the MIB files? -------------------------------- Probably not. The MIB files play two main roles - they are used to translate between numeric OIDs and the corresponding textual names, and they define the structure and syntax of the relevant MIB objects. This second role is perhaps best thought of in terms of a design document. It's vital while developing an application (typically the MIB module or handler within the agent), since it defines what the application (MIB) must actually do. But once the code has been written, the design document becomes redundent. The agent then has the same information hardcoded into it (literally!), and no longer needs the MIB file. The translation task is not strictly necessary - SNMP will operate fine without any MIB files at all, as long as you're happy to work with numeric OIDs throughout, and know which MIB objects you're interested in. But it's much easier to work with the (hopefully) meaningful names, enumeration tags and the like, and to view the description of a particular object. This requires having the relevant MIB files installed and loaded. Since the agent needs MIBs the least and some systems are memory restricted, it is possible to completely disable loading these MIBs as well as remove the code that does the parsing by using the --disable-mib-loading flag to configure. However, note that certain snmpd.conf tokens actually make use of mib information so they won't be as easily usable. AGENT ===== What MIBs are supported? ----------------------- The following MIBs are supported (at least in part and on some systems): - MIB-2 General network statistics (RFC 1213 and subsequent revisions) - Host Resources (RFC 1514 and 2790) - SNMPv3 framework (RFCs 2571-5, 3411-3418) (including USM, VACM, Target and Notification MIBs) - DisMan Event and Schedule MIBs - MTA-MIB (sendmail) - private UCD/Net-SNMP agent extensions (monitor specified processes and disks, memory, CPU, load average, + extending the agent using shell commands) See README.agent-mibs for details. Not all MIB modules are included by default on all systems. Some of these may need to be explicitly requested when the software is first configured and built, while others may not be available on all architectures. There are a few other MIB implementations distributed as part of the source tarball, but these are basically unsupported and most of the core developers have little or no experience with using them. What protocols are supported? ---------------------------- The agent supports all three current versions of SNMP (v1, v2c and v3), over both UDP and TCP transports, as well as acting as a SMUX (RFC 1227) master agent, AgentX (RFC 2741) in both master and subagent roles, and SNMP proxying. How do I configure the agent? ---------------------------- That's a somewhat ambiguous question, as there are two very different stages where it is possible to "configure" the agent. Firstly, you can determine what capabilities and defaults are included within the library and agent, at the time that the software is first built. This uses suitable flags to the 'configure' script, before compiling the source. As far as the agent is concerned, the most significant option is '--with-mib-modules' (or '--with-out-mib-modules') to control which MIBs will be supported by the agent. See the next few entries for details. You can also control various aspects of the agent behaviour (and the information it returns) at run time, via the 'snmpd.conf' configuration file. Various aspects of this are touched on throughout this FAQ. Or see the snmpd.conf(5) manual page for full details. The "snmpconf" script can help in creating this config file. Start off with 'snmpconf -g basic_setup' to get you going. How do I remove a MIB from the agent? ------------------------------------ Deleting the text file for a MIB does not affect the agent (other than to prevent it from recognising MIB object names in the config files). It's necessary to tell the agent not to activate the relevant code that actually implements these objects. There are three ways to do this: 1) re-run 'configure' to exclude the given MIB module(s) from the build configuration, then recompile and reinstall: ./configure --with-out-mib-modules=path/to/unwanted .... make make install This specifies the path to the module code file, relative to the 'agent/mibgroup' directory. Clearly, this approach is only possible if you are working with a source distribution. 2) disable the MIB at runtime snmpd -I -unwanted Note that this relies on knowing which modules are used to implement the relevant MIB objects. If you're not sure, you could try walking the 'nsModuleName' MIB object, which indicates the module responsible for each particular range of OIDs. You can also check which MIB modules are loaded by getting the agent to report them as they are initialised: snmpd -Dmib_init -H From this information, it should then be fairly obvious which modules to disable. 3) use access control to exclude the mib from the view used to query the agent: view almostEverything included .1 view almostEverything excluded unwantedMib rocommunity public default -V almostEverything This approach can also be used with the full com2sec/group/access configuration directives (e.g. with versions earlier than 5.3, which don't support the above mechanism). I've installed a new MIB file. Why can't I query it? ---------------------------------------------------- Installing a new MIB file will not magically enable the agent to know what values to report for the objects defined in that MIB. It's necessary to have some code which can provide the relevant information. The next few entries, and the CODING section address this issue in more detail. How do I add a MIB to the agent? ------------------------------- Adding a MIB essentially involves writing some code to implement the objects defined in the new MIB. There are three basic approaches that can be used to do this: - The agent can invoke an external command or shell script to return the necessary information. There are several possible variations on this approach - see the next entry for details. - The agent can pass the request off to another (sub-)agent, which already implements the required MIB. Again, there are several ways of doing this - including AgentX, SMUX and proxied SNMP. See the next entry but one for details. - You can write code to implement the new MIB objects, and include this within the agent. This is most commonly C (or C++) code, although the agent can also support MIB modules implemented in perl. See the next section (CODING) for more details. Note that there is no visible difference between external commands, subagents, and modules implemented within the main agent itself. Tools querying the agent will see a single MIB structure. What's the difference between 'exec', 'sh', 'extend' and 'pass'? --------------------------------------------------------------- 'exec' will run the specified command and return the exit status and output. Any arguments are passed directly to the command, with no special interpretation. 'sh' is similar, but invokes a shell to run the command line given. This means that quoted arguments will be recognised as such, and also allows redirection, and other similar shell interpretation. The results are returned in exactly the same way. 'extend' is also similar, but provides a richer and more flexible MIB framework - both for configuring the exact command to be run, and for displaying the results. None of these mechanisms require the command to have any knowledge of SNMP, or the fact that they are being used in this manner. But the output is returned in a fixed format, and it is up to the receiving application to interpret this appropriately. Note that the "relocatable" form of the 'exec' directive ('exec OID ....') produces MIB output that is not strictly valid. For this reason, support for this has been deprecated in favour of 'extend OID ...', which produces well-formed MIB results (as well as providing fuller functionality). The most recent releases of the agent don't include support for "relocatable exec" by default. This needs to be explicitly included when the agent is first compiled, by including the module 'ucd-snmp/extensible' instead of 'agent/extend'. 'pass' is a more general mechanism for implementing arbitrary MIB objects. The specified command will be invoked for any request within the named MIB subtree, and passed details of the requested OID. It should return the information relevant to the requested OID. 'pass-persist' is similar, but the command will continue running even after the initial request has been answered. These two mechanisms can be used to implement a particular MIB, following the correct MIB structure (as opposed to the fixed format of exec/sh/extend). All of these mechanisms are described in the 'snmpd.conf(5)' man page, in the section entitled "Extending Agent Functionality". What's the difference between AgentX, SMUX and proxied SNMP? ----------------------------------------------------------- All three are protocols that can be used to make two or more agents appear as one to the querying application. In each case, one agent takes the role of "master", and delegates requests to one of the others as and where this is appropriate. The differences between them mainly relate to how data is represented, and the mechanisms for communication between master and subagents. SMUX and proxy SNMP both essentially use the standard SNMP packet format. The main difference is that a proxy SNMP subagent need not be aware that it is acting in such a role. It typically listens on a non-standard port, and simply receives requests as usual, forwarded from the master agent (rather than directly). The main issue to be aware of is that such requests will appear to come from the local host, and this may affect how the access control mechanisms need to be set up. SMUX uses a similar packet format, but the subagent "registers" with the master agent, providing a suitable password. The Net-SNMP (and UCD) agent includes the possibility of acting as a SMUX master agent, but the suite does not include a subagent API. Note that support for SMUX is not included by default, and needs to be explicitly enabled by running: --with-mib-modules=smux before re-compiling the agent. See the file 'agent/mibgroup/README.smux' for details. AgentX uses a more compact (and simpler) packet format, with a richer range of administrative commands, and provides a more flexible and reliable extension mechanism. The Net-SNMP agent can be used in both master and subagent roles, and the agent library can also be used to embed an AgentX subagent within another application. See the file 'README.agentx' for details. AgentX support is included by default, but needs to be explicitly activated in the master agent. Do this by adding the line master agentx to the snmpd.conf file before starting the agent. What is the purpose of 'dlmod'? ------------------------------ Most of the MIB information supplied by the Net-SNMP agent is provided by C-coded implementation modules, and the choice of which modules to include is usually made when the agent is first built. Adding new MIB modules would therefore require re-compiling the agent. This is not always convenient - particularly when working with a production system, and/or pre-installed binaries. Dynamically loaded modules are a means of including a MIB implementation module within the main SNMP agent (or an AgentX subagent) without needing to re-compile and re-link the agent binary. Instead, details of the module(s) to load are specified in the configuration file, and the agent locates the files listed, and merges them in at run time. See http://www.net-snmp.org/tutorial-5/toolkit/dlmod/ for more information. Which extension mechanism should I use? -------------------------------------- That's not easy to answer in general. If there's an existing agent that already implements the desired new MIB, then it makes sense to re-use that, via whatever extension protocol that agent might support. Note that the SMUX protocol has essentially been superceded by AgentX, which provides a fuller and more reliable mechanism than either SMUX or proxied SNMP. So ideally, this would be the preferred extension approach. But if the target subagent only supports SMUX or basic SNMP, then that would dictate the extension protocol to use. Implementing the module in C within the main agent (directly or via dlmod) is probably the most efficient and reliable, closely followed by embedded perl (or python) extensions. These have the advantage of minimal overheads between the code implementing the MIB module, and the agent framework, and no inter-process communication issues. But this does assume that there's a suitable mechanism for retrieving the necessary information. If the new MIB is monitoring or managing some other subsystem, external to the agent, then it may be necessary to embed a subagent within the subsystem itself - particularly if there's no suitable public API to retrieve the necessary information. In this case, AgentX is probably the most appropriate way forward. Alternatively, you could implement the missing public management API for that subsystem, and develop a module within the main agent instead. Can I use AgentX when running under Windows? ------------------------------------------- Yes, but there are a couple of things to be aware of. Firstly, by default the AgentX master listens on the Unix domain socket '/var/agentx/master', which doesn't work under Windows. You'll need to tell it to listen on a TCP port, either by using the command-line option "-x localhost:705", or by adding the directive "agentxSocket localhost:705" to the snmpd.conf file. Secondly, be aware that the security of AgentX connectivity is not particularly strong. The examples given here would allow any process running on the local machine to register as an AgentX subagent. The more obvious settings "-x 705" or "agentxSocket 705" would allow a system *anywhere* on the network (or even from remote networks) to register as an AgentX subagent. This could potentially be used to hijack the agent, or provide false information. How can I run AgentX with a different socket address? ---------------------------------------------------- There are two sides to an AgentX connection, and they need to agree about which socket address to use. So if you want to use a different socket, you need to configure both parties accordingly. The socket that the Net-SNMP master agent uses to listen for AgentX registrations (and send appropriate requests) can be specified using the option '-x'. The command "snmpd -x tcp:localhost:705 ...." would start the agent listening on the TCP port 705 for connections from the local system. The same effect can also be obtained by adding the line agentxsocket localhost:705 to the file 'snmpd.conf'. The same option can be used with the Net-SNMP agent when running in This also holds when the Net-SNMP agent is running in "subagent" mode, to specify the socket to register with (and receive requests from). So a subagent might connect to the master agent above (both running on the same host), using: "snmpd -X -x tcp:localhost:705 ...." A subagent running embedded within some other application will typically not understand the same command-line options, so would need to set the same configuration programmatically: netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_X_SOCKET, "tcp:localhost:705"); With the example subagent code from the Net-SNMP tutorial, this line would be added immediately before the 'init_agent' call. The same approach can also be used to listen on a different named socket, using: agentxsocket /tmp/agentx agentxperms 770 770 myuser mygroup or snmpd -x /tmp/agentx .... or netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_X_SOCKET, "/tmp/agentx"); as appropriate. How can I turn off SMUX support? ------------------------------- Normally, you would use the command-line option '-I -{module}' to disable the initialisation of a particular MIB module within the agent. Unfortunately, it's not currently possible to turn off SMUX support this way. The safest approach is to run configure --with-out-mib-modules=smux and recompile the agent. If this is not possible, an alternative workaround might be to have the agent bind the SMUX socket to an invalid IP address, using a snmpd.conf line such as: smuxsocket 1.0.0.0 The agent may complain at startup, but it won't accept any incoming SMUX requests. If the agent complains about not recognising the "smuxsocket" token, then you're out of luck. You'll either have to recompile from source, or use local firewall rules to block connections to port 199. How can I combine two copies of the 'mib2' tree from separate subagents? ----------------------------------------------------------------------- This is the purpose of the SNMPv3 'context' field. Register the MIB module a second time in a non-default context (see the relevant entry in the CODING section for details), and specify this context when querying the agent. The MIB module can use this context information to determine which set of information to report. Or you could register two completely different handlers for the same OID (using different contexts), and the agent will invoke the appropriate code. This holds for both MIB modules implemented within the main agent, or AgentX subagents - the same approach will work for both. Contexts can also be used with proxied SNMP requests - just specify the option '-Cn {context}' as part of the "proxy" entry. See the 'snmpd.conf(5)' man page for details. It's currently not possible to support parallel MIB trees when using SNMPv1 or SNMPv2c. In principle, it should be possible to use the community string in a similar way, but this has not (yet) been implemented. This mechanism is only available with the v5 Net-SNMP agent. The v4 UCD agent does not support contexts at all. Sorry about that. Another way to handle this would be to tweak one of the subagents to use a different set of (non-standard) OID assignments - perhaps by relocating the whole of the subtree to another (private) OID. This is not ideal, but should work with all configurations. What traps are sent by the agent? -------------------------------- The Net-SNMP agent sends a 'coldStart(0)' trap when it first starts up, and an enterprise-specific trap 'nsNotifyShutdown' when it stops. It generates an enterprise-specific trap 'nsNotifyRestart' (rather than the standard 'coldStart(0)' or 'warmStart(1)' traps) on receiving a HUP signal - typically after being re-configured. It can also be configured to send an 'authenticationFailure(4)' trap when it receives an SNMPv1 (or SNMPv2c) request using an unknown community name. The agent does not send 'linkUp' or 'linkDown' traps by default. It can be configured to do this using the directive 'linkUpDownNotifications'. See the 'snmpd.conf(5)' man page (under ACTIVE MONITORING) for details. Similarly, it does not generate traps by default when one of the monitored characteristics (disk usage, running processes, etc) enters or leaves an error state. This can be configured using the 'defaultMonitors' directive (again documented under ACTIVE MONITORING). Where are these traps sent to? ----------------------------- With all these alerts, the agent needs to be told where to send them, specifying the type of notification (v1 or v2 trap, or v2 inform) and the community name to use. This uses the snmpd.conf directives 'trapsink', 'trap2sink' and 'informsink' for the destination type, and 'trapcommunity' for the community name. SNMPv3 destinations can be configured using the directive 'trapsess'. See the 'snmpd.conf(5)' man page for details. Note that the type of trap generated is totally determined by these directives - irrespective of which API call was used to trigger sending the trap. See the trap-related entries in the CODING section for details. Note also that you typically only want *one* of the settings: trapsink localhost trap2sink localhost informsink localhost Including two (or all three) of these lines in the snmpd.conf file will will result in multiple copies of every notifications being sent for each call to 'send_easy_trap()' (or 'send_v2trap()'). This is probably not what was intended! How can I send a particular trap to selected destinations? ---------------------------------------------------------- This is not currently possible. All notifications will be sent to all configured destinations. The agent does not (currently) support notification filtering. There is a preliminary implementation of the snmpNotifyFilterTable which is designed to allow this sort of selective trap direction. However this is not currently active. (The tables are present and can be manipulated and updated, but the information is not consulted) Documentation on how to use this mechanism will appear once the functionality is working properly. When I run the agent it runs and then quits without staying around. Why? ----------------------------------------------------------------------- Firstly, are you certain that this is what is happening? The normal operation of the agent is to 'fork' itself into the background, detaching itself from the controlling terminal so that it will continue running even when you log out, and freeing the command line for subsequent use. This looks at first sight as if the agent has died, but using 'ps' to show all processes should reveal that the agent is still running. To prevent this behaviour (such as when attempting to debug the agent), you can start it with the '-f' flag. This suppresses the fork, and the agent will run as a 'normal' command. It's also often useful to use the '-Le' (or '-L') flag, to log messages to stderr. On the other hand, if 'ps' shows that the agent is not running, then this is an error, and probably show that something went wrong in starting the agent up. Check the agent log file for any error messages, or run it with '-f -Le' and see what it reports. One possible cause might be an existing agent (or some other process) that's already listening on the SNMP port. Trying to start a second agent will fail with an error about "opening the specified endpoint". If you're starting the agent as a non-root user, then this may also fail with the very same error. By default, the agent (and trap handler) will attempt to listen on the standard SNMP port 161 (or 162 for the trap handler). These are defined as "privileged ports", and processes will need to be running as root in order to open them. One way to tackle this is to start the agent as root, but use the -u option to switch to run as another user once the port has been opened. Alternatively, you can specify a different port to use instead. Anything greater than 1024 is available to non-root users. In this case, you'll also need to specify the same port when issuing client commands. After a while the agent stops responding, and starts eating CPU time. Why? -------------------------------------------------------------------------- This is basically the same problem described in the APPLICATIONS section, in the entry The agent worked for a while, then stopped responding. Why? See that entry for details. How can I stop other people getting at my agent? ----------------------------------------------- Firstly, are you concerned with read access or write access? As far as changing things on the agent is concerned, there is relatively little that can actually be altered (see the entry "Why can't I set any variables in the MIB?" above). If you are using the example config file, this is set up to allow read access from your local network, and write access only from the system itself (accessed as 'localhost'), both using the community name specified. You will need to set appropriate values for both NETWORK and COMMUNITY in this file before using it. This mechanism can also be used to control access much more precisely. (see the next few questions for details) Other options include: - Blocking access to port 161 from outside your organisation (using filters on network routers) - Using kernel-level network filtering on the system itself (such as IPTables) - Configuring TCP wrapper support ("--with-libwrap") This uses the TCP 'libwrap' library (available separately) to allow/deny access via /etc/hosts.{allow,deny} For strict security you should use only SNMPv3, which is the secure form of the protocol. However, note that the agent access control mechanisms does not restrict SNMPv3 traffic by location - an SNMPv3 request will be accepted or rejected based purely on the user authentication, irrespective of where it originated. Source-based restrictions on SNMPv3 requests would need to use one of the "external" mechanisms listed above. How can I listen on just one particular interface? ------------------------------------------------- Normally, the agent will bind to the specified port on all interfaces on the system, and accept requests received from any of them. However, if a particular port (or ports) is specified when the agent is first started, then it will only listen for requests on these particular ports. For example: snmpd 127.0.0.1:161 would listen (on the standard port) on the loopback interface only, and: snmpd 10.0.0.1:6161 would listen on port 6161, on the (internal network) interface with address 10.0.0.1. To listen on both of these interfaces (and no others) provide a list of all the desired addresses: snmpd 127.0.0.1:161 127.0.0.1:6161 The AgentX port option ('-x') works in much the same way. The agent is complaining about 'snmpd.conf'. Where is this? ----------------------------------------------------------- It doesn't exist in the distribution as shipped. You need to create it to reflect your local requirement. To get started, you can either just create this file manually, or run snmpconf to help you create one. At the very least, you will need some form of access control configuration, if the agent is to be of any use whatsoever. This can be as simple as: rocommunity public See the snmpd.conf(5) manual page or relevant entries in this FAQ for further details. Why does the agent complain about 'no access control information'? ----------------------------------------------------------------- Although an SNMP agent may support a wide range of management information, it is not necessarily appropriate to report the whole of this to every SNMP management station who asks for it. Some information may be sensitive, and should restricted to authorized administrators only. SNMP therefore includes mechanisms for controlling who has access to what information - both in terms of what can be seen, and (even more importantly) what can be changed. By default, the Net-SNMP agent starts up with a completely empty access control configuration. This means that *no* SNMP request would be successful. It is necessary to explicitly configure suitable access control settings, based on who should be granted access in that particular environment. If there are no access control entries configured (perhaps because no snmpd.conf configuration file has been loaded, or it contains no access control settings), then the agent will not respond to any SNMP requests whatsoever. This is almost certainly not what was intended, so the agent reports this situation. See the next entry for how to configure access control settings. How do I configure access control? --------------------------------- The simplest way is to use the configure directives: rocommunity public (for SNMPv1/2c) rwcommunity private or rouser user1 (for SNMPv3) rwuser user2 These specify the community names or security names to accept for read-only and read-write access to the whole of the supported MIB tree. (Obviously you should change these names to match your requirements - which is a particularly good idea in the case of 'rwcommunity'!) Note that you should *not* specify the same community name for both rocommunity and rwcommunity directives. The rwcommunity setting automatically provides read access, and having both lines (with the same community name) may result in unexpected behaviour. Only use both settings when specifying *different* community names. The same holds true for rouser and rwuser. The two community directives can be restricted to only allow requests from particular sources, and all four can be restricted to a particular subtrees or (from v5.3) a named view. See 'snmpd.conf(5)' for details. How do I configure SNMPv3 users? ------------------------------- There are three ways to configure SNMPv3 users: 1) Stop the agent, and add the line createUser {myUser} MD5 {myPassword} DES to the file /var/net-snmp/snmpd.conf (where {myUser} and {myPassword} are the appropriate values for username and password, _without_ the braces!). Then re-start the snmpd agent. 2) Stop the agent, run the command net-snmp-config --create-snmpv3-user and follow the prompts given. This will create an entry in the /var/net-snmp/snmpd.conf file similar to the above. Then re-start the snmpd agent. 3) Make sure the agent is running, and will respond to an SNMPv3 request (using an existing user with the desired authentication and privacy protocols). Then use the 'snmpusm' command to clone this template user, and change the password. See the access control entries above and the file 'README.snmpv3' for more details about how to use SNMPv3 users, Note that simply having a 'rouser' or 'rwuser' line does *not* automatically create the corresponding SNMPv3 user. You will need the above 'createUser' line (or an equivalent 'usmUser') as well. The 'createUser' line disappears when I start the agent. Why? ------------------------------------------------------------- This is deliberate. The agent removes the (human-readable) 'createUser' directive, and replaces it with an equivalent 'usmUser' entry. This contains the same information, but in a form that's only meaningful internally. Not only is the passphrase no longer visible in the config file, it has actually been converted to a key that is only valid on this particular system. If someone stole the configuration file, they could not use the information from the usmUser entry to access any of your other agents (even if the usernames and passwords were the same). What's the difference between /var/net-snmp and /usr/local/share/snmp? --------------------------------------------------------------------- The /var/net-snmp location is primarily used for information set during the running of the agent, which needs to be persistent between one run of the agent and the next. Apart from "createUser" (see the previous entry), you shouldn't need to touch this file. All other user-provided configuration should go in the traditional location (typically /usr/local/share/snmp/snmpd.conf or /etc/snmp). My new agent is ignoring the old snmpd.conf file. Why? ----------------------------------------------------- The most likely explanation is that the new version of the agent is looking in a different location than the previous one. This is commonly experienced when replacing a ready-installed version (e.g. from a vendor distribution), with the current release installed from the source. Try moving the old config file to the new location, and restart the agent. If you're not sure where this should go, see the next entry. Where should the snmpd.conf file go? ----------------------------------- The default location for this file with the basic distribution is /usr/local/share/snmp/snmpd.conf (or PREFIX/share/snmp/snmpd.conf). Ready-installed versions often look for the file as /etc/snmpd.conf, or /etc/snmp/snmpd.conf. If you are still not sure, try running the command snmpd -f -Le -Dread_config 2>&1 | grep "config path" The first line of output will display the list of locations where the agent is looking for configuration information. Why am I getting "Connection refused"? ------------------------------------- This is actually nothing to do with the access control mechanism (though that's an understandable mistake). This is the result of the TCP wrapper mechanism using the files 'hosts.allow' and 'hosts.deny' to control access to the service. Some distributions may come with this enabled automatically - otherwise you need to explicitly activate this by running configure --with-libwrap and recompiling the agent. If TCP wrappers are enabled, and both hosts.allow and hosts.deny are empty, then all requests will be rejected (with "Connection refused"). The simplest way to avoid this problem and allow incoming requests is to add the line snmpd: ALL to the file /etc/hosts.allow. Be aware that doing this removes one level of protection and allows anyone to try and query your agent. The agent's own access control mechanisms can still be used to restrict what - if anything - they can see. If you do wish to use the TCP wrappers to restrict access, it's sensible to have an explicit entry: snmpd: ALL in the file /etc/hosts.deny, which makes it crystal clear that access to the SNMP agent has been denied. This mechanism can also be used to restrict access to specific management hosts, using a hosts.deny entry such as: snmpd: ALL EXCEPT 127. which will allow connections from localhost, and nothing else. Note that personal firewalls, such as the Linux iptables mechanism, may have a similar effect (though typically this won't be logged). See the earlier entry Requests always seem to timeout, and don't give me anything back. Why? Why can't I see values in the UCDavis 'proc' or 'disk' trees? ------------------------------------------------------------------ Both these trees are designed to report precisely those things that have been explicitly configured for monitoring. If there are no relevant configuration entries in the snmpd.conf file, then these tables will be empty. See the snmpd.conf manual page and the EXAMPLE.conf file for details on configuring the agent. Optionally, run snmpconf -g monitoring to help you set up this section of the snmpd.conf file. Why can't I see values in the UCDavis 'memory' or 'vmstat' trees? ---------------------------------------------------------------- These trees do not need any explicit configuration, and should be present automatically. However the C code necessary to implement these particular MIB modules are not supported on all operating systems. These trees will be omitted on any system for which there is no underlying code. Currently, they are only supported on Linux, HP-UX (memory only), Solaris, BSDi (vmstat on BSDi4 only), Dynix, FreeBSD, NetBSD and OpenBSD. If you want to help port it to other systems, let us know. Note that these subtrees only report the current usage when explicitly queried. They do *not* automatically generate traps when the usage strays outside the configured bounds. See the earlier FAQ entry What traps are sent by the agent? or the snmpd.conf section on active monitoring, for more information. What do the CPU statistics mean - is this the load average? ---------------------------------------------------------- No. Unfortunately, the original definition of the various CPU statistics was a little vague. It referred to a "percentage", without specifying what period this should be calculated over. It was therefore implemented slightly differently on different architectures. The 5.4 release has clarified the situation, and standardised on calculating these percentages over a minute. The relevant MIB descriptions have been updated to make the desired behaviour more explicit. The Net-SNMP agent also includes "raw counters", which can be used to calculate the percentage usage over any desired period. This is the "right" way to handle things in the SNMP model. The original percentage objects have been deprecated, and may possibly be removed in a future release of the agent. Note that this is different from the Unix load average, which is available via the loadTable, and is supported on all architectures. How do I get percentage CPU utilization using ssCpuRawIdle? ----------------------------------------------------------- This one of the "raw counters" mentioned in the previous entry. You need to take two readings of this object and look at the difference between them. That difference divided by the total number of 'ticks' between the two readings (where one tick is probably 0.01 seconds) will give you the percentage utilization over that period. What about multi-processor systems? ---------------------------------- The CPU objects (both percentages and raw counters) were designed to monitor the overall CPU activity of a system, and typically reflect whatever the underlying operating system reports for the (single) CPU statistics information. How these are handled for a multi-CPU system will differ from one O/S to another, and will need to be investigated for each system individually. The htProcessorTable was designed to handle monitoring multi-CPU machines, but the Net-SNMP implementation has up to now treated most systems (with the honourable exception of Solaris, and more recently Linux) as implicitly single-CPU. With the 5.4 release, there is now a cleaner framework for reporting on multi-CPU equipment, and it is hoped that an increasing number of systems will be able to report suitable processor information. Also with the 5.4 release, for the first time the agent will report the hrProcessorLoad value properly, which should provide some simple per-CPU statistics. The speed/type of my network interfaces is wrong - how can I fix it? ------------------------------------------------------------------- Some operating systems will provide a mechanism for determining the speed and type of network interfaces, but many do not. In such cases, the agent attempts to guess the most appropriate values, usually based on the name of the interface. The snmpd.conf directive "interface" allows you to override these guessed values, and provide alternative values for the name, type and speed of a particular interface. This is particularly useful for fast-ethernet, or dial-up interfaces, where the speed cannot be guessed from the name. See the snmpd.conf(5) man page for details. The interface statistics for my subinterfaces are all zero - why? ---------------------------------------------------------------- Unfortunately, most kernels that support multiple logical interfaces on a single physical interface, don't keep separate statistics for each of these. They simply report the overall statistics for the physical interface itself. There's no easy way around this problem - the agent can only report such information as is available. If the kernel doesn't keep track of these figures, the agent can't report them. Sorry! Does the agent support the RMON-MIB? ----------------------------------- Not really. There is an "Rmon" code module included within the agent source code tree, but this is best thought of as a template for the RMON-MIB statistics groups, rather than a full implementation. With most MIBs, the hardest part of implementing the MIB is often getting hold of the data to report. This is definitely true of the RMON-MIB, which relies on gathering (and analysing) a potentially large quantity of network traffic. The Rmon code distributed with the Net-SNMP agent code avoids this problem, by using random data. Some of the functionality of the RMON-MIB, such as the alarm and event groups, has since been superseded by the work of the DisMan IETF working group. The Net-SNMP agent does implement these (more general) MIB modules. But the statistics gathering aspects of the RMON-MIB are not readily available. Note too that none of the core developers have any significant experience with this code, and the person who originally wrote it is no longer active on the mailing lists. So there's no point in asking on the lists whether these modules work or not. You've got the source - how badly do you need this functionality? What does "klread: bad address" mean? ------------------------------------- This means that the agent was unable to extract some of the necessary information from the kernel structures. This is possibly due to: - either looking in the wrong place for kernel information (check the value of KERNEL_LOC) - an error in the implementation of part of the MIB tree for that architecture. Try and identify which OID is generating the error, and contact the list 'net-snmp-coders@lists.sourceforge.net' Remember to tell us what architecture you have! What does "nlist err: wombat not found" (or similar) mean? ---------------------------------------------------------- This means that the agent wasn't able to locate one of the kernel structures it was looking for. This may or may not be important - some systems provide alternative mechanisms for obtaining the necessary information - Solaris, for example, can produce a whole slew of such messages, but still provide the correct information. This error only occurs if you have used the flag '--enable-debugging' as part of the initial configuration. Reconfigure the agent with '--disable-debugging' and these messages will disappear. (It won't fix the underlying problem, but at least you won't be nagged about it). What does "Can't open /dev/kmem" mean? ------------------------------------- This device is normally restricted to just being accessible by root (or possibly by a special group such as 'kmem' or 'sys'). The agent must be able to read this device to obtain the necessary information about the running system. Check that the agent was started by root, and is running with UID 0 (or suitable GID if appropriate). The agent will normally continue to run without this level of access permission, but won't be able to report values for many of the variables (particularly those relating to network statistics). The system uptime (sysUpTime) returned is wrong! ----------------------------------------------- Oh no it's not. The defined meaning of 'sysUpTime' is "the time ... since the *network management* portion of the system was re-initialized." In other words, when the snmp agent was started, not when the system itself last booted. This latter information is available in the Host Resources MIB as "hrSystemUpTime.0" Note that even if the full Host Resources is not supported on your system, it's worth configuring in the system portion using '--with-mib-modules=host/hr_system' and recompiling. This particular group is reasonably likely to work, even if some of the other more architecture-specific groups don't. Can the agent run multi-threaded? -------------------------------- Short answer - no. Longer answer - not easily. Net-SNMP within a single thread of an threaded application is fine, as long as *all* snmp code is kept within the same thread. This lets you add SNMP support to an existing threaded application. If you are concerned with the time taken for to process requests for a particular agent, object or subtree, and you want the agent to continue to respond to other requests in the meantime, there are two options. The first method is using AgentX sub-agents. If you have several tables, each implemented by a separate subagent, then a single request for entries from each of the tables will be processed in parallel (and the agent will continue to respond to other requests while it waits for the subagents to return the necessary information). But a request for several objects from the same table will be passed off to the relevant subagent, where it will (normally) be processed serially. The second method is to use delegated requests + IPC to another process. If takes a long time to retrieve a value for a given object, then the object handler could do whatever necessary to start or communicate with another (non-SNMP) process/thread to actually retrieve the value, and mark the request as delegated. The main agent (or subagent) can then receive and process other requests while waiting for the delegated request to finish. Dealing with resource contention is all up to you. All of this only applies to the GET family of requests. A SET request will block until all pending GET requests have finished, and then will not accept new requests until the SET is complete. Adding full multi-thread support directly to the agent would be nice. We just need someone with time/money to do/sponsor the work. Can I use AgentX (or an embedded SNMP agent) in a threaded application? ----------------------------------------------------------------------- With care. As mentioned in the earlier "thread-safe" FAQ entry, the Net-SNMP agent (including the AgentX subagent) has not been designed for threaded operation. In particular, it makes use of various global variables without attempting to protect them against simultaneous use. This means that it is *NOT* safe to have SNMP or AgentX related processing in two separate threads. This also applies to handling GET (and SET) processing in one thread, and generating traps in another. This is still vulnerable to the usual threading problems. However, as long as *all* of the SNMP-related activity is limited to the one thread, then there should be no reason why this cannot safely communicate with other threads within the same application, using private (thread-safe) mechanisms. But in terms of the Net-SNMP-provided code, the agent (and AgentX subagent) should *not* be regarded as thread-safe. COMPILING ========= How do I control the environment used to compile the software? ------------------------------------------------------------- The basic mechanism for compiling the Net-SNMP project software is to run "configure", followed by "make" (to compile it), "make test" (to check that it's working properly) and then "make install" (to install the files into the correct locations - which typicalyl needs to be done as root. The primary role of "configure" is to determines various aspects about the system that the software is being compiled on. However there are also a number of options to configure which can be used to control various aspects of the compilation environment. The most common options are "--with-mib-modules" and "--with-out-mib-modules" which control the set of MIB module code files that are included within the agent binary. Adding or removing these modules will affect what MIB information the agent can return. See the entry "How do I add a MIB to the agent?" for more details. The configure script can also specify the compiler to use for compiling the source code (e.g. "configure --with-cc=cc"), the flags passed to this compiler (e.g. "configure --with-cflags=-g"), or to the linker (e.g. "configure --with-ldflags=-Bstatic"), and various other aspects of the build environment. Run "configure --help" for a full list. How do I control the environment used to compile the software under Windows? --------------------------------------------------------------------------- If you are compiling the project within the MinGW or Cygwin environments, then these use the same "configure" mechanism as Unix-based systems. See the previous entry for more information. If you are compiling the project from within Visual Studio, then this does not use the standard configure mechanism. Instead, there is a separate "Configure" script within the 'win32' directory. This can be used enable or disable various aspects of the build environment, such as support for encryption or IPv6. Run "Configure --help" for more information Note that this script does not include an equivalent of "--with-mib-modules" for extending the MIB information supported by the agent. Instead, this needs to be done by tweaking the build environment manually. See the file README.win32 for more details of this, and various other aspects of building the project on Windows systems. Why does the compilation complain about missing libraries? --------------------------------------------------------- This has been seen in a number of guises over the years - most commonly on Linux systems (although the problem may also occur elsewhere). The underlying problem is that typical installation may not always include the full set of library links required for building the Net-SNMP software. This problem can usually be fixed by installing the missing packages (typically the development version of a package that is already there). Examples of this that we have come across include: -lelf elfutils-devel (later renamed to elfutils-libelf-devel) -lbz2 bzip2-devel -lselinux libselinux-devel -lcrypto openssl/openssl-devel -lbeecrypt libbeecrypt/beecrypt/beecrypt-devel. These are the names of the RedHat/Fedora RPMs. Other distributions or O/S's may use different names, but the basic idea should be the same. If the compilation is complaining about a missing .so file, then an alternative quick fix is to add the missing symbolic link, using something like: ln -s libelf.so.1 /usr/lib/libelf.so giving the appropriate generic library name from the error message, and the correct number for whichever version of this library you have installed. If the compilation is complaining about a .la file, then you should install the relevant development package, as listed above. How can I reduce the memory footprint? -------------------------------------- In order to reduce the memory footprint (for instance, to embed the snmpd into a device), the following configure options could be used. '--disable-debugging' This turns off the compilation of all debugging statements. '--enable-mini-agent' '--with-out-mib-modules=examples/ucdDemoPublic' This creates an agent with just the essential MIB modules included. NOTE: If you need additional MIB modules, then simply add them using the option '--with-mib-modules=...' but this will of course increase the memory footprint. '--with-transports=UDP' This option specifies the transport domains to include. For a simple standalone agent, just UDP should be sufficient. (Although the 'disman' and 'agentx' modules may require the Callback, TCP and/or Unix transport domains as well). '--without-kmem-usage' This can be used in order to omit the code that operates on the /dev/kmem interface. Clearly, this option cannot be used when one of the configured MIB modules depends on it. '--with-mibdirs=' and '--with-mibs=' These options tell the agent not to load any MIB modules. This doesn't affect the size of libraries or application binaries, but will reduce the memory footprint during runtime. '--disable-mib-loading' This can be used in order to omit the code that loads and parses the MIB files altogether. This will reduce both the runtime memory footprint, and the binary sizes. Once the agent (snmpd) has been linked, you might also try running 'strip snmpd' to remove un-necessary debug/symbol information. How can I reduce the installation footprint or speed up compilation? ------------------------------------------------------------------- The following configure options may also be useful: --disable-agent Do not build the agent (snmpd). --disable-applications Do not build the apps (snmpget, ...). --disable-manuals Do not install the manuals. --disable-scripts Do not install the scripts (mib2c, ...). --disable-mibs Do not install the mib files. --disable-mib-loading Do not include code that parses and manipulates the mib files. How can I compile the project for use on an embedded system? ----------------------------------------------------------- Although this is definitely a Frequently Asked Question on the project mailing lists, it hasn't really been a Frequently _Answered_ Question. The basic problem is that none of the core development team have much involvement or experience with embedded systems. And although we have repeatedly put out a plea for implementation reports and advice, this has not so far been particularly successful. So the first thing to say is that the following suggestions should be treated with a greater than usual level of suspicion. The second thing to say is that compiling the Net-SNMP project for use on an embedded system typically means compiling the *agent* (rather than the trap receiver, or command-line tools). So that is what this entry will concentrate on. There are three main aspects to consider: - how to compile the code, - *what* code to compile, and - how to install the resulting agent binary. The Net-SNMP project uses the standard "configure" mechanism, so the usual cross-compilation options are available - in particular "--host" and "--target". It is also possible to specify the compiler and linker to use ("--with-cc" and "--with-ld"), and any special flags to pass to them ("--with-cflags" and "--with-ldflags"). There shouldn't be anything particularly special about compiling the Net-SNMP code, so see the documentation for your target environment for more information. (And please let us know if there *is* anything special that should be mentioned here!) If the aim is simply to generate an SNMP agent to run on the target system, it's probably not necessary to compile the command-line tools or trap receiver. The configure option "--disable-applications" will omit these elements. See the previous entry for other potentially relevant useful options. Unfortunately, the SNMP agent (and in particular, the code for individual MIB modules) is the most system-specific part of the Net-SNMP software. It may prove necessary to disable particular MIB modules if they do not compile successfully, or attempt to use the wrong system-specific APIs. This can be done using the configure option "--with-out-mib-modules". Alternatively, the option "--enable-mini-agent" will omit all but the core MIB module code. Additional modules can then be added individually using "--with-mib-modules". Further information about how to deal with problems with individual MIB modules is reliant on suitable reports being forthcoming from the wider Net-SNMP community. The ball is in your court! Finally, installing the agent binary is _not_ simply a matter of copying the "snmpd" file onto the target system. The agent typically relies on a number of additional libraries (and possibly the presence of assorted MIB files, unless this has been explicitly omitted). It is normally necessary to run "make install", before copying the installed framework to the target system. If the install destination needs to be different to the eventual location on the target system, this can be handled using the configure options "--prefix" (for the target location) and "--with-install-prefix" (for the temporary install location). Alternatively, this can be handled as part of the install command: make install prefix={target location} INSTALL_PREFIX={temp location} Alternatively, if the agent is compiled with static linking (and no MIB files), then it may be possible to simply copy the agent binary across to the target system. See the next entry for details. How can I compile the project to use static linking? --------------------------------------------------- For totally static net-snmp executables, use configure --with-ldflags=-Bstatic To compile your application with static libraries (eg for easier debugging), and to link to a non-installed build directory, try the following Makefile fragment: NETSNMPDIR=/usr/local/build/snmp/full-clean-cvs-V5-1-patches NETSNMPCONFIG=$(NETSNMPDIR)/net-snmp-config NETSNMPBASECFLAGS := $(shell $(NETSNMPCONFIG) --base-cflags) NETSNMPINCLUDES := $(shell $(NETSNMPCONFIG) --build-includes $(NETSNMPDIR)) # base flags after build/src include, in case it has /usr/local/include NETSNMPCFLAGS=$(NETSNMPINCLUDES) $(NETSNMPBASECFLAGS) NETSNMPBASELIBS := $(shell $(NETSNMPCONFIG) --base-agent-libs) NETSNMPEXTLIBS := $(shell $(NETSNMPCONFIG) --external-agent-libs) NETSNMPLIBDIRS := $(shell $(NETSNMPCONFIG) --build-lib-dirs $(NETSNMPDIR)) NETSNMPLIBDEPS := $(shell $(NETSNMPCONFIG) --build-lib-deps $(NETSNMPDIR)) LIB_DEPS=$(NETSNMPLIBDEPS) LIBS=$(NETSNMPLIBDIRS) -Wl,-Bstatic $(NETSNMPBASELIBS) -Wl,-Bdynamic $(NETSNMPEXTLIBS) STRICT_FLAGS = -Wall -Wstrict-prototypes CFLAGS=-I. $(NETSNMPCFLAGS) $(STRICT_FLAGS) This replaces the standard Makefile section, which will used installed libraries: NETSNMPCONFIG=net-snmp-config # uncomment this if you have GNU make #NETSNMPCFLAGS := $(shell $(NETSNMPCONFIG) --base-cflags) #NETSNMPLIBS := $(shell $(NETSNMPCONFIG) --agent-libs) NETSNMPCFLAGS=`$(NETSNMPCONFIG) --base-cflags` NETSNMPLIBS=`$(NETSNMPCONFIG) --agent-libs` LIBS=$(NETSNMPLIBS) Why does 'make test' skip various tests? --------------------------------------- Some of the tests are only relevant to particular operating systems, or rely on specific areas of functionality. The test framework will check whether the relevant elements are available before running the relevant tests, and will skip them if these modules have been omitted from the build environment (or do not apply to the current system). One example of this are the tests T053agentv1trap, T054agentv2ctrap, T055agentv1mintrap, T056agentv2cmintrap and T113agentxtrap, which rely upon functionality from the NET-SNMP-EXAMPLES-MIB implementation. This module is not included in the default agent configuration, so the test framework will skip these tests. To include them, run "configure --with-mib-modules=examples/example" and re-compile. Why does 'make test' complain about a pid file? ----------------------------------------------- Typically it says something like: cat: cannot open /tmp/snmp-test-1-8694/*pid* It's trying to tell you the port is blocked - typically because another copy of the agent is still running, left over from from a previous testing run. If you type 'ps -ef' you should notice an orphaned process like: snmpd -d -r -U -P /tmp/snmp-test-5-27295/snmpd.pid... Kill this process. This could be happening for several reasons including: 1. You are trying to do concurrent runs of 'make test'. 2. On a slow machine, the agent might be taking too long to start up. Try changing the value of the variable SNMP_SLEEP in testing/RUNTESTS from 1 to something higher - say 3 or 5. CODING ====== How do I write C code to integrate with the agent? ------------------------------------------------- There are three main methods for integrating external C code within the agent. The code can be compiled directly into the agent itself, it can be loaded dynamically while the agent is running, or it can be compiled into a separate application (a "subagent") which communicates with the main master agent. All three approaches have been touched on elsewhere within this FAQ. As far as the module code is concerned, all three mechanisms use exactly the same module API. So a module developed for use directly within the agent, could also be included within a subagent, or loaded dynamically with no (or minimal) code changes needed. Most of this section is concerned with more detailed aspects of developing such code - including the 'mib2c' tool, which can handle generating a basic code framework for implementing a given set of MIB objects. How does the agent fetch the value of a MIB variable from the system? -------------------------------------------------------------------- That's typically the hardest bit of implementing a new MIB module, and is the one thing that 'mib2c' can't help with. It very much depends on the MIB variable concerned (and often the underlying operating system as well). Relatively few MIB modules are completely self-contained, with all the information held internally within the agent, and all updates being done via SNMP requests. Such MIB modules can be implemented fairly easily. More commonly, the agent needs to provide an SNMP-based interface to information held elsewhere, perhaps in the operating system kernel or some other application. Handling this is much more complex - since a lot depends on what mechanisms are provided for retrieving (and possibly updating) this information. The mib2c tool can generate code for processing SNMP requests, based on some internal cache of management information, but it cannot help with populating this cache with the underlying data. That is up to the MIB implementer. See the existing MIB modules in the Net-SNMP source tree for various examples of assorted approaches to this task. Mib2c complains about a missing "mib reference" - what does this mean? --------------------------------------------------------------------- This basically means that it hasn't loaded the MIB file containing the definition of the MIB subtree you're trying to implement. This might be because it hasn't been installed, the name is wrong, or (most likely), because it isn't in the default list. See the MIBS section for more details, or the next entry for suitable invocations of 'mib2c'. Mib2c complains about not having a "valid OID" - what does this mean? --------------------------------------------------------------------- This probably means that you gave it the name of a MIB file (or module), rather than the name of an object defined in that file. Mib2c expects the name of a 'root' object, and will generate a template for the sub-tree starting from there. If you've got a file 'MY-MIB.txt', defining the MIB module 'MY-MIB' which contains a subtree based on the object 'myMib', then you should invoke mib2c as "mib2c .... myMib" rather than "mib2c .... MY-MIB.txt" or "mib2c .... MY-MIB" Note that you'll probably also have to add your MIB to the list of MIBs that are loaded automatically, in order for mib2c to recognise the name of this object. So the command would typically be "MIBS=+MY-MIB mib2c .... myMib" or "MIBS=ALL mib2c .... myMib" Why doesn't mib2c like the MIB file I'm giving it? ------------------------------------------------- This is most likely the same problem as the previous entry. Mib2c takes the name of a MIB _object_, not the name of a file (or MIB module). Try using the name of the MODULE-IDENTITY definition. Another possibility is that the MIB may contain syntax errors. Try running it through 'snmptranslate' or a dedicated SMI validation tool (such as 'smilint' or the on-line interface at http://wwwsnmp.cs.utwente.nl/ietf/mibs/validate/) Mib2c ignores my MIB and generates a pair of 'mib-2' code files. Why? --------------------------------------------------------------------- This is usually a sign of the same problem as the previous entries, giving mib2c the name of the file containing the MIB (or of the MIB itself), rather than an object within it. Earlier versions of mib2c didn't detect this situation, and merrily constructed a template for a default starting point of the mib-2 node. More recent versions complain about not having a valid OID instead. What's the difference between the various mib2c configuration files? ------------------------------------------------------------------- Most of the mib2c config files are concerned with implementing MIB tables, and generate various alternative code templates. These basically fall into four distinct categories. 'mib2c.raw-table.conf' is the lightest of the templates, and just provides a fairly basic table framework. Most of the work of implementing the table - detecting which row is required for a given request, retrieving or updating the relevant column values, and interacting with the underlying subsystem - are all left to the MIB programmer. The second group of templates - 'table_data', 'container' and 'tdata' - all share the same basic model (although the internal details are rather different). The MIB implementer should define a data structure to represent a row of the table, and the helper then takes care of holding the table internally, as a collection of such per-row data structures. This includes identifying which row is required for a given request. Retrieving or updating the appropriate column value is left to the MIB programmer, although the generated framework includes most of the necessary code. Allied to this is a fourth "internal data" mib2c configuration file ('create-dataset') which handles the individual columns as well. This is the closest to a Plug-and-Play configuration, and the MIB implementer only needs to be concerned with any special processing, such as linking the table with the underlying subsystem. The third style of mib2c config assumes that the table data is held externally to the helper - either within the MIB module code itself, or in the external subsystem. The generated code framework includes routines to "iterate" through the rows of the table, with the iterator helper simply deciding which row is required for a particular request. Once again, the MIB programmer must handle retrieving or updating the appropriate column value, although the generated framework includes most of the necessary code. There is a variant of this config ('iterate_access') which works in basically the same way. However this tries to separate out the standard processing, from the code that needs to be amended by the programmer for retrieving and updating the individual column values. This is also the idea behind the final table-oriented mib2c config template - 'mib2c.mfd.conf' (or "MIBs for Dummies"). This is a much more flexible framework, which can be used with either internally held data, or iterating through an external representation. The distinguishing feature of this framework is that it separates out standard and table-specific processing, at a much finer level of detail than the others. The other mib2c config templates are concerned with implementing scalar objects ('scalar', 'int_watch'), code to generating traps ('notify'), and various specialised requirements. There is also a template ('old-api') to generate code suitable for the previous v4 UCD agent - though this is not particularly complete or reliable. It's probably better to use a pure v4 mib2c environment (or switch wholeheartedly to the v5 style). Which mib2c configuration file should I use? ------------------------------------------- The answer to that heavily depends on the characteristics of the MIB objects being implemented. Of the handler-based table frameworks, 'tdata' is more appropriate for tables that can be stored (or a copy cached) within the agent itself, while 'iterate' is more relevant to reporting data from outside the agent. The raw interface is only suitable in very specific circumstances, so it's probably sensible to start with one of the other frameworks first, and only look at this if none of the alternatives seem to work. The decision between the handler-based configs and MfD is more a matter of the style of programming to use. Most of the frameworks define a single handler routine to process an incoming request, so all of the code is listed together, with the MIB programmer inserting table-specific processing into this single block of code. The MfD provides a series of individual object-specific routines, each concerned with one very specific task, and hides as much as possible from the programmer. If you like to understand the broad thrust of what's happening, then one of the handler-based approaches would be the best choice. If you prefer to concentrate on the nitty-gritty of a given table, and are happy to trust that the rest of the processing will work correctly, then the MfD framework would be more appropriate. For implementing a group of scalar objects, then the choice is simple - use 'mib2c.scalar.conf'. Similarly, for generating traps or informs, use 'mib2c.notify.conf'. But note that this only assists with the code to actually generate the trap. It does not address the issue of _when_ to send the trap. See the FAQ entry "How can I get the agent to generate a trap?" for more information. How can I have mib2c generate code for both scalars and tables? -------------------------------------------------------------- This uses a very powerful tool called a "text editor" :-) The mib2c tool uses separate configuration files to generate code for scalar objects, and for tables. This means that it's not possible to automatically generate a single code file that supports both scalars and tables. Instead, the two code files need to be generated separately, and then combined manually. This will typically mean copying the handler routines for the scalar object(s) into the table file, and adding the code to register these handler(s) to the table initialisation routine. Are there any examples, or documentation for developing MIB modules? ------------------------------------------------------------------- Many of the MIB modules shipped with the Net-SNMP agent still use the v4 "traditional" MIB module API, but an increasing number use one of the newer v5 helper-based handlers. All of these can be found under 'agent/mibgroup' The 'tdata' helper is used in the new DisMan Event, Expression and Schedule MIB modules (see 'disman/{event,expr,schedule}/*'). The similar 'dataset' helper is used in the older DisMan Event MIB implementation (see 'disman/mteEvent*') and the Notification Log MIB (see 'notification-log-mib/*'), used by 'snmptrapd' to log incoming traps. The basic iterator handler is used in the TCP and UDP table implementations (mibII/tcpTable & mibII/udpTable), VACM context handling (mibII/vacm_context) and various tables relating to agent internals (agent/*). These show a number of different approaches to using the iterator helper, so it's worth comparing them. The two examples/netSnmpHostsTable* modules provide a contrast between the iterator and iterator_access helpers. There are several examples based on the MfD framework (see '{if,ip,tcp,udp}-mib/'). Much of this code is not intended to be viewed directly, but individual files are clearly commented to distinguish between internal implementation and public code. The Net-SNMP agent does not currently include any MIB modules using the array-user container-based helper. The best examples of this are to be found in the net-policy project. See http://net-policy.sourceforge.net/ Where should I put the files produced by 'mib2c'? ------------------------------------------------ If you're using the main source tree to compile your new module, then put these two files (mymib.[ch]) in the directory 'agent/mibgroup'. You should then re-run configure to add in your new module configure --with-mib-modules=mymib and recompile. If you've got a number of new modules to add, it might be sensible to put them all into a single subdirectory of 'mibgroup'. Then create a header file, listing the individual components. This might look something like: config_require(mymib/myObjects) config_require(mymib/myTable) config_require(mymib/myOtherTable) If this was saved as the file 'mymib.h', then the same configure line given above, would pull in all three modules. See the current contents of 'agent/mibgroup' for examples of this. Note that the MfD framework will generate a similar grouping automatically. Why doesn't my new MIB module report anything? --------------------------------------------- There are probably four main reasons why a new MIB module isn't working. Either it hasn't been included in the running agent, the code is present but hasn't been initialised, the module has been initialised but the handler isn't being called, or there's a problem with the module code itself. To check whether the code files are being compiled, the easiest approach is simply to look at the directory where the code is located. When the agent is compiled, this should produce .o files (and probably .lo files) corresponding to the C code files for this module. Alternatively, run 'nm' (or 'strings') on the MIB module library (libnetsnmpmibs), and look for the names of the initialisation routines or handlers (or the text of any messages displayed by the module code). One other thing to check is whether you have multiple copies of the software installed on the system. This is a particular problem when compiling from source (to include your new module), without first removing any vendor-supplied version of the agent (which won't include this new code). Assuming that you have confirmed that the module code is present in the agent, the next step is to check whether the initialisation routine is being called to register the MIB objects. The simplest way to do this is to include a suitable debugging statement within the initialisation routine, and start the agent with the corresponding '-Dtoken'. Alternatively, try walking the nsModuleName column object, and look for mention of the new MIB module. Assuming the module has been registered, the next step is to check whether the handler is being called, when the agent receives a suitable SNMP request. Again, the simplest way to do this is to include debugging statements within the handler routine, and start the agent with the corresponding '-Dtoken'. Then issue an "snmpget" request for an instance within the new MIB module. (This command is preferable to the usual "snmpwalk" command, as it is more closely focused on the MIB module in question). If this indicates that the handler routine isn't being called, then there are two main likely causes. Firstly, check the access control settings. If these are configured to block access to this portion of the OID tree, then the MIB handler will never be called. Secondly, several of the table helpers are designed to know which rows of the table are valid, and will call the main MIB handler with information about the relevant row. If the requested row is not valid (or the table is empty), then the handler will not be called. Finally, if the handler _is_ being called, but is still not returning any information, then the cause probably lies with your MIB module code. In which case, it's really up to you to find the problem and fix it! Either activate any debugging code that you have included within the handler routine, or run the agent under a source code debugger, and step through the handler processing. In either case, it's much easier to debug these problems when processing an "snmpget" request, rather than "snmpgetnext" or "snmpwalk". Remember that 'mib2c' simply generates template code for your MIB module. It's up to you to fill in the details, to report the actual information from whatever underlying subsystem is being monitored. Mib2c cannot help with the semantics of the MIB module - it's purely there to provide an initial code framework, based on the _syntax_ of the MIB module objects. Why does the iterator call my get_{first,next} routines so often? ----------------------------------------------------------------------- The first thing to realise is that the 'get_first' and 'get_next' hook routines are concerned with processing a single SNMP request, not with walking the whole table. A full "snmpwalk" command will typically involve a series of individual 'GetNext' requests, and every one of these will trigger a separate 'get_first/get_next/get_next/....' cycle. It's usually more efficient to use 'snmptable' which will walk each column in parallel (as well as displaying the results in a more natural manner). Secondly, the iterator helper was originally designed to handle unsorted data, so will look at every row of the internal table for each request. If the data is actually held in the correct order, then it's worth setting the NETSNMP_ITERATOR_FLAG_SORTED flag: iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info); iinfo->flags |= NETSNMP_ITERATOR_FLAG_SORTED; This will help the situation somewhat. But the iterator helper is inherently a relatively inefficient mechanism, and it may be worth looking at one of the other helpers, particularly if the data will be held within the agent itself. How can I get the agent to generate a trap (or inform)? ------------------------------------------------------ There are two aspects to having the agent generate a trap - knowing *how* to do this, and knowing *when* to do so. Actually generating a trap is reasonably simple - just call one of the trap API routines ('send_easy_trap()' or 'send_v2trap()') with the relevant information (generic and specific trap values, or a varbind list respectively). The 'mib2c.notify.conf' configuration file can be used to construct a suitable template routine for generating a trap, including building the variable list from the MIB trap definition. These variables can then be given suitable values, before invoking the 'send_v2trap()' call to actually send the trap. See the 'snmp_trap_api(3)' man page for further details. Note that these APIs are only available within the agent (or subagents), and are not available to stand-alone applications. The code for 'snmptrap' shows an approach to use in such a case. Determining *when* to generate the trap (either directly or via the mib2c-generated routine) is often harder. If the trap is generated in response to some action within the agent, (e.g. as the result of a SET), then this isn't too much of a problem. But if the trap is intended to report on a change of status (e.g. a network interface going up or down, or a disk filling up), then actually detecting this is non-trivial. Unless the underlying system can signal this situation to the agent, then it's typically necessary to poll the value(s) on a regular basis, save the results and compare them with the new values the next time round. The simplest way to handle this is via the DisMan Event MIB, which is designed for exactly this purpose. As long as you can specify a MIB object to monitor, and the value or thresholds that should trigger a notification, then this module can check these values regularly, and automatically send a suitable trap when appropriate. See the 'snmpd.conf(5)' man page (under ACTIVE MONITORING) for details. Otherwise, you'd need to use the routines documented in 'snmp_alarm(3)' to regularly invoke a monitoring routine. This would check the necessary conditions (which need not be MIB objects), and call the 'send_xxx_trap()' routine (as generated by 'mib2c.notify.conf') when appropriate. How can I get an AgentX sub-agent to generate a trap (or inform)? ---------------------------------------------------------------- This is done in exactly the same manner as with the main SNMP agent. Calling one of the routines described in 'snmp_trap_api(3)' will cause the AgentX sub-agent to send a notification to the master agent, which will then pass this on to the configured trap destination(s). One of the original design aims of the Net-SNMP AgentX support was that the agent (or subagent) framework should be transparent to a MIB module implementer. The interface between the agent framework and a MIB module should be independent of the protocol used to receive the original request. So the exact same MIB module code could be used within a traditional SNMP-only agent, or an AgentX subagent, with no changes needed. This also holds for sending traps. How can I get the agent to send an SNMPv1 (or SNMPv2c) trap? ----------------------------------------------------------- It doesn't make any difference whether you use the v1-style API call 'send_easy_trap()' or the v2-style 'send_v2trap()'. What matters is the directive(s) in the snmpd.conf file. If this file contains 'trapsink', then the agent will send an SNMPv1 trap. If this file contains 'trap2sink', then the agent will send an SNMPv2c trap. And if this file contains both, then the agent will send *two* copies of this trap. See the entry Where are these traps sent to? in the AGENT section for details. How can I get the agent to include varbinds with an SNMPv1 trap? --------------------------------------------------------------- There are two ways to do this. You can either use the 'send_v2trap()' call and give a varbind list, starting with the v2-equivalent of the SNMPv1 trap, followed by the additional varbinds. Alternatively, you can use the API call 'send_trap_vars()' which takes the same generic/specific trap values as 'send_easy_trap()', plus the list of additional varbinds. In either case, you also need to have 'trapsink' in the snmpd.conf file. The resulting trap will be identical, whichever approach is used. How can I get the agent to send an SNMPv1 enterprise-specific trap? ------------------------------------------------------------------ There are two ways to do this. You can either use the 'send_v2trap()' call and give a varbind list, starting with the v2-equivalent of the SNMPv1 trap, followed by the additional varbinds. Alternatively, you can use the (undocumented) API call 'send_enterprise_trap_vars()' which takes the same parameters as 'send_trap_vars()', plus the enterprise OID to use (in the usual name/length form). See the code file 'agent_trap.c' In either case, you also need to have 'trapsink' in the snmpd.conf file. The resulting trap will be identical, whichever approach is used. How can I get the agent to send an SNMPv3 trap (or inform)? ---------------------------------------------------------- It doesn't matter which API call you use to specify the trap - 'send_easy_trap()', 'send_v2trap()' or one of the other calls mentioned above. Generating an SNMPv3 notification (rather than a community-based one) is controlled by the snmpd.conf file. To send an SNMPv3 trap, this file should contain a 'snmpsess' directive, specifying the version, security level, user name and passphrases (if applicable), as well as the destination address. This is basically the same as the command line required for sending the trap manually, using 'snmptrap'. Note that (unlike 'snmptrap') this directive does *not* read default settings from an 'snmp.conf' file, so these must be specified explicitly in the 'snmpsess' line. Why does calling 'send_v2trap' generate an SNMPv1 trap (or vice versa)? ---------------------------------------------------------------------- The two versions of the trap API calls are concerned with how the trap is represented when it is passed *in* to the API, not the version of the trap PDU that will actually be generated by the agent. That is determined by the configuration token used to set up the trap destination. Remember that in general, all traps are sent to all destinations. This means that a trap specified using the SNMPv1 trap syntax needs to be converted to the SNMPv2 format before it can be sent to an SNMPv2 (or SNMPv3) destination. Similarly, a trap specified using the SNMPv2 syntax needs to be converted to the SNMPv1 format before it can be sent to an SNMPv1 sink. Essentially, the API call to use depends on what you asking for, which is not necessarily what the recipients will actually get! See 'snmp_trap_api(3)' for a fuller explanation. How can I register a MIB module in a different (SNMPv3) context? --------------------------------------------------------------- Contexts are a mechanism within SNMPv3 (and AgentX) whereby an agent can support parallel versions of the same MIB objects, referring to different underlying data sets. By default, a MIB module registrations will use the default empty context of "". But it's also possible to provide MIB information using a different (non-default) context. There are three aspects involved in doing this. Firsly, it's necessary to register the MIB module in this non-default context. With the v4 API, this uses the call 'register_mib_context()' rather than the REGISTER_MIB macro. This is significantly more detailed, but most of the additional parameters can take fixed values, if all that's needed is to change the registration context. Instead of the macro call: REGISTER_MIB("my_token", my_variables, variable1, my_variables_oid); use the function call: register_mib_context( "my_token", my_variables, sizeof(variable1), sizeof(my_variables)/sizeof(variable1), my_variables_oid, sizeof(my_variables_oid)/sizeof(oid), DEFAULT_MIB_PRIORITY, 0, 0, NULL, "my_context", -1, 0); Things are much easier with the v5 helper-based API. Having created the registration structure, this just requires setting the 'contextName' field before actually registering the MIB module: netsnmp_handler_registration *reg; reg = netsnmp_create_handler_registration(.....); reg->contextName = strdup("my_context"); netsnmp_register_handler(reg); Secondly, it is necessary to configure the access control settings to allow access to information in the new context. This is handled automatically when using the simple "rouser" or "rwuser" directives. But if access control is configured using the fuller com2sec/group/view/access mechanism, then the "access" line must specify the appropriate context(s), either explicitly: access {group} "my_context" any noauth exact ...... or using a single entry to cover all possible contexts: access {group} "" any noauth prefix ...... Finally, the SNMP request used to retrieve (or update) the information must also specify the required context. With SNMPv3 requests, the context is part of the protocol, so this can be done using a command-line option: snmpwalk -v 3 -n my_context ..... With community-based requests (SNMPv1 and SNMPv2c), things aren't so simple. Although the "rocommunity" and "rwcommunity" settings also configure access for all possible contexts, there's no way to specify a non-default context as part of the request. The only way to handle non-default contexts with community-based SNMP requests is to set up a mapping from the community string to the desired context. This uses the "com2sec" directive, with an additional "-Cn" parameter. Note that this also means that the access control must be configured using the full com2sec/group/view/access mechanism. The short-form access control directives do not handle the mapping of community strings to non-default contexts. MISC ====== What ASN.1 parser is used? ------------------------- The parser used by both the agent and client programs is coded by hand. This parser has recently been re-vamped to allow control of which of the available MIBs should be included, and to handle duplicate object subidentifiers. The source code can be found in the snmplib directory (in 'parse.c'), and the parser is usually bundled into the library 'libnetsnmp.a' Note that the parser attempts to be fairly forgiving of some common errors and incompatibilities in MIB files. The Net-SNMP tools accepting a MIB file without complaint does *not* imply that the MIB is strictly correct. Certain MIBs may need some amendments to allow them to be read correctly by the parser. Contact the coders' list for advice. What is the Official Slogan of the net-snmp-coders list? ------------------------------------------------------- "The current implementation is non-obvious and may need to be improved." (with thanks to Rohit Dube) And an alternate, added 26-Apr-2000: "In theory, it shouldn't be that hard, but it just needs to be done." usr/share/doc/socat/FAQ000064400000007401152532166430010700 0ustar00 Q: What is the clue of socat? A: socat probably doesn't have any clue. It is more an attempt to smoothly integrate similar I/O features that are usually handled differently under UNIX. Q: What does the prefix XIO mean? A: XIO means "extended input/output". It is a library/API that provides a common way for handling files, sockets and other forms of I/O. Its advantage is that the application may reduce its I/O to open / read+write / close calls, while the user controls all I/O details (and even basic process properties) by packing options into the filename string. This is the basic part of socat. Q: Is there a Windows port of socat available? A: Try with Cygwin from http://www.cygwin.com/, or upgrade to Linux. Q: I succeeded to configure and make socat, but ./test.sh says something like: ./test.sh: No such file or directory A: You need a bash shell in your executable path (locations in $PATH) Q: configure disables readline / openssl / libwrap support because it does not find an include file / the library. How can I tell configure where these files are? A: For include locations, use the environment variable CPPFLAGS, for library locations use LIBS, e.g.: export CPPFLAGS="-I/home/user/ssl/include" export LIBS="-L/home/user/ssl/lib" On some systems (SunOS), you might also need to set LD_LIBRARY_PATH: export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/home/user/ssl/lib" Then try again: make distclean; ./configure; make Q: I succeeded to make socat, but the test.sh script fails for many tests. Is my socat build corrupt? A: Probably your socat program is ok; the tests have been developed on Linux 2.4, and there they usually succeed. But the following OS differences result in errors on non Linux systems: * Linux allows to bind a socket to any address of range 127.0.0.0/8, not only 127.0.0.1. Some tests are built on this feature, but they might fail on other systems. * Your OS might have no IP6 implementation * MacOS X has some difficulties, e.g. distinguishing sockets and pipes. * the OpenSSL tests require OpenSSL support by socat, must have openssl in $PATH, and "openssl s_server ..." needs enough entropy to generate a key. Q: When I specify a dual address (two partial addresses linked with "!!") on the command line, I get some message "event not found", and my shell history has the line truncated. Not even protecting the '!'s with '\' helps. A: '!' is appearently used by your shell as history expansion character. Say "set +H" and add this line to your (bash) profile. Q: On Solaris, socat was built successfully, but when started, it gets killed with something like "ld.so.1: ./socat: fatal: libreadline.so.4: open failed: no such file or directory" A: The configure script finds your libreadline, but the runtime loader doesn't. Add the directory where the library resides to your LD_LIBRARY_PATH variable, e.g.: LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/sfw/lib/ make distclean; ./configure; make Q: On Solaris, socat was built successfully, but when started, an assertion fails: "xioinitialize.c:25: failed assertion `3 << opt_crdly.arg3 == CRDLY' A: Probably, in a second attempt you set the correct LD_LIBARY_PATH for socat, but it had not been set during the ./configure run, or you did not "make clean" before running configure. Try it again: make distclean; ./configure; make Q: A socat process, run in background from an interactive shell, is always stopped with all its child processes after about 5 minutes. killall -9 socat is required to clean the system and allow socat to be started again. A: The terminal (window) might have the TOSTOP flag set and one of the socat processes wants to write to the terminal. Clear this flag in your shell: stty -tostop and start socat again. Thanks to Philippe Teuwen for reporting this situation. usr/share/doc/mc/FAQ000064400000102727152532204610010166 0ustar00GNU Midnight Commander Frequently Asked Questions The newest version of this document is available at http://www.midnight-commander.org/browser/doc/FAQ * 1 Getting started + 1.1 What is Midnight Commander? + 1.2 Does it run on my machine? + 1.3 Does it work with my terminal? + 1.4 What else do I need to run MC? + 1.5 Is GNU Midnight Commander Public Domain? Copyrighted? + 1.6 Where can I get GNU Midnight Commander? + 1.7 I cannot compile MC. What should I do? * 2 Keyboard + 2.1 What does documentation mean with the C-?, M-? and F? keys? + 2.2 Why don't function keys (or some other key) work? + 2.3 How do I use function keys F11 to F20? + 2.4 Why does the ESC key behave funny? + 2.5 How can I add the plus sign (+) on the command line? + 2.6 C-o doesn't work! + 2.7 What 'keys' are the "a1" and "c1" keys mentioned in the manual? + 2.8 How do I change the key bindings? * 3 Mouse + 3.1 How do I enable mouse support? + 3.2 How do I cut and paste text with mouse? + 3.3 How do I get the extension dependent pop-up menu to pop up? * 4 Display + 4.1 Why do I keep getting "Terminal not powerful enough for SLang" or "Terminal not powerful enough for SLsmg"? + 4.2 Why don't line drawing characters work? + 4.3 Can one use latin-1 characters without losing the lines? + 4.4 I have problems with entering/viewing national characters! + 4.5 How can I get colors? + 4.6 My color_xterm goes completely (or partially) black! + 4.7 Where can I get xterm or rxvt? + 4.8 I got colors working with MC but the other programs don't work at all anymore! + 4.9 Why are there both terminfo and termcap? Wouldn't one database be enough? * 5 Graphical user interface + 5.1 Xview, Tk and Gnome editions? + 5.2 Why is MC linked with X libraries? * 6 Command line problems + 6.1 How do I stay in the last directory when I exit Midnight Commander? + 6.2 How can I access command line history? + 6.3 How can I complete commands, file names, variable names and so on? + 6.4 I am using ksh. Can I use functions defined in the .kshrc within MC? + 6.5 Is there any way to include additional options or hot keys to MC? + 6.6 When I use Ctrl-O I don't get a subshell. How do I fix this? + 6.7 Ctrl-O doesn't work at all. What happens? * 7 Virtual file systems + 7.1 How can I see the contents of a tar archive? + 7.2 How do I get out of a tar archive? + 7.3 How do I do anonymous ftp with MC? + 7.4 How do I do non-anonymous ftp with MC? + 7.5 How do I close an ftp connection? + 7.6 Why aren't the contents of ftp panel updated? + 7.7 What kind of proxy server works with Midnight Commander? * 8 Internal editor + 8.1 When I try pasting to the internal editor, it indents the amount of indenting increases with each line! + 8.2 Is it possible to use Colorer for syntax highlighting? * 9 Other common problems + 9.1 Is there any way to 'bookmark' favorite ftp-fs links? + 9.2 When I start Midnight Commander, nothing happens! * 10 Development + 10.1 Who has written Midnight Commander? + 10.2 Do I dare to use a development version? + 10.3 How can I report a bug/request for a feature? + 10.4 How can I join the development? * 11 More information + 11.1 This document didn't answer my question. Where else can I look for an answer? + 11.2 What mailing lists are there for Midnight Commander? + 11.3 Where should I look on the World Wide Web for MC stuff? + 11.4 Are the mailing lists archived anywhere? * 12 Legal issues + 12.1 Authorship + 12.2 Feedback is invited + 12.3 Disclaimer and copyright 1 Getting started 1.1 What is Midnight Commander? GNU Midnight Commander is a user-friendly yet powerful file manager and visual shell, useful to novice and guru alike. It provides a clear, user-friendly, and somewhat protected interface to a Unix system while making many frequent file operations more efficient and preserving the full power of the command prompt. After some practice, you will wonder how you could ever live without it. 1.2 Does it run on my machine? GNU Midnight Commander runs on POSIX (Unix-like) operating systems, such as GNU/Linux, FreeBSD, Mac OS X, Solaris, HP-UX and others. It can also be compiled under Cygwin on Windows. GNU Midnight Commander uses GNU Autoconf which should automatically configure it for every Unix clone. Following configurations have been tested in the past (this list is very old): * i386-*-linux1.x, 2.x * alpha-linux-linux2 * sparc-linux-linux2.x * sparc64-linux-linux2.1 * mips-sgi-irix5.x, 6.x * mips-dec-ultrix4.3 * rs6000-ibm-aix3.2.5 * sparc-sun-sunos4.1 * sparc-sun-solaris2.3, 2.4, 2.5 * sparc-sun-netbsd1.0 * hppa-hp-hpux9 * hppa-hp-hpux7 * m68k-apple-aux * unixware * mc88110-aviion-dgux5.4R2.01 * i386-*-sco3.2v4.2 * i386-*-sco3.2v5 1.3 Does it work with my terminal? Yes, it does. Because GNU Midnight Commander is a full screen program it doesn't run on dummy terminals but anything more advanced will do (like vt100). If your terminal works with vi, emacs, elm or pine it will work with GNU Midnight Commander. 1.4 What else do I need to run MC? You need a POSIX (Unix compatible) operating system. If you are running Windows, use Cygwin. To compile any edition you need to have glib 2.x installed. It's available at ftp://ftp.gtk.org/pub/gtk/. If you want to use mouse on the Linux console you need the gpm daemon from ftp://ftp.systemy.it/pub/develop/. You need nothing extra to use mouse on xterm. If you do not want to use the S-Lang library you could try using ncurses version 4.1 and above. 1.5 Is GNU Midnight Commander Public Domain? Copyrighted? Midnight Commander is under GNU Public License which basically means that you may freely copy, change and distribute it, but that you may not impose any restrictions on further distribution, and that you must make the source code available. This is not the same as Public Domain. For details, the GNU license is included in GNU Midnight Commander source distribution (the COPYING file). Midnight Commander is now officially a part of the GNU project. All the authors of GNU Midnight Commander have given all their rights on the program to the Free Software Foundation. 1.6 Where can I get GNU Midnight Commander? The main site is http://www.midnight-commander.org 1.7 I cannot compile MC. What should I do? Make sure you have read the INSTALL file in the sources. Report the error messages exactly as they appear, mention the versions of your OS, your compiler and whatever else software you think is relevant. If you have compile problems in the VFS code, try disabling it by using "--disable-vfs" option. f2 Keyboard 2.1 What does documentation mean with the C-?, M-? and F? keys? GNU Midnight Commander documentation uses emacs style names for keyboard keys. C stands for the Ctrl key. For example, C-f means that you should hold down the Ctrl key and press the f key. M stands for the Meta key. Your terminal might call it Alt or Compose instead of Meta. For example, M-f means that you should hold down the Meta/Alt/Compose key and press the f key. If your terminal doesn't have Meta, Alt or Compose or they don't work you can use Esc. For M-f press the Esc key and then press the f key. Sometimes Ctrl and Alt are used instead of C and M for simplicity. Keep in mind that Alt can actually be Meta on some keyboards. F? stands for a function key. If your terminal doesn't have function keys or they don't work you can use Esc. For example, for F3 press the Esc key and then press the 3 key. 2.2 Why don't function keys (or some other key) work? Your terminfo or termcap database has missing or incorrect definitions for function keys. Type "mc -V" to see what terminal database is being used. If the result is "using the S-Lang library with terminfo database" and you are using a very old terminfo database, consider installing one of the enhanced terminfo files included in GNU Midnight Commander source distribution. For example, if you are using xterm type "tic xterm.ti". If the result is "using the S-Lang library with termcap database" you should fix your /etc/termcap database. Up-to-date termcap and terminfo databases are available here: http://www.catb.org/~esr/terminfo/ ftp://ftp.gnu.org/pub/gnu/ncurses/ If you don't have permissions to edit terminal databases you can use Learn keys feature of Midnight Commander instead. Press Esc 9 o k and follow instructions. If all else fails you can emulate function keys by first pressing the ESC key and then one of the number keys. For example, if you want to produce F9, press ESC, then 9. If you don't have a ESC key on your keyboard you can try alt-9 or meta-9. 2.3 How do I use function keys F11 to F20? These are normally mapped to function keys F1 to F10 with Shift held, e.g. function key F13 can be activated by pressing Shift-F3. You can define the keys this way in the Options->Learn Keys dialog. The convention for PC keyboards is that F11-20 always means Shift with F1-10. You may find that on the Linux console with some keyboard layouts Shift-Fn is interpreted as F(n+12), not as F(n+10). This is a result of non-uniformity of keyboard layouts. This is not an intended behavior and it may be fixed some day. In the meantime, use "Learn Keys" to remedy this inconvenience. 2.4 Why does the ESC key behave funny? Midnight Commander uses the ESC key as a prefix for simulating the Meta and Alt keys (for terminals which don't have Meta or Alt, see the three previous questions). For example, pressing ESC-a is the same as pressing Meta-a. In addition most terminals use ESC for internal representation of arrow keys, function keys and other enhanced keys. If you want to use ESC to cancel things you have to press it twice i.e. ESC-ESC. If you find this cumbersome you can generally use F10 to cancel. Alternatively turn on the old_esc_mode setting in the ~/.config/mc/ini file. The old_esc_mode setting makes ESC work as a prefix only if another key is pressed within 0.5 seconds. After 0.5 seconds the ESC key cancels. There is no way to make ESC cancel immediately (if we want to be able to use arrows keys and function keys). 2.5 How can I add the plus sign (+) on the command line? Press C-q first, then press the + sign. The plus key is the hotkey for the select files command. If you want to add a literal plus on to the command line you must quote it by pressing C-q first. Another common key which needs the C-q prefix is backslash "\". 2.6 C-o doesn't work! Maybe C-o is a stty control character on your terminal. See man stty for details on how to list and change stty control characters. 2.7 What 'keys' are the "a1" and "c1" keys mentioned in the manual? The "a1" key is the key which has the "a1" caption on it. The "c1" key is the key which has the "c1" caption on it. If you have to ask what these two keys are your keyboard hasn't probably got them. Actually, I have never seen a keyboard which has got them. 2.8 How do I change the key bindings? There is no generic way to reconfigure the key bindings. You can use the "Learn Keys" dialog to assign keys to some actions listed in that dialog. However, most actions cannot be redefined to use different keys. 3 Mouse 3.1 How do I enable mouse support? Invoke mc like this (without quotes): "mc -x". If this doesn't work upgrade to a terminal which compatible with the Xterm mouse sequences. Alternatively, on Linux console you can use gpm. 3.2 How do I cut and paste text with mouse? Hold down shift key while using mouse to cut and paste. 3.3 How do I get the extension dependent pop-up menu to pop up? It was developed for the GNOME edition. The text-mode edition doesn't support this feature yet. 4 Display 4.1 Why do I keep getting "Terminal not powerful enough for SLang" or "Terminal not powerful enough for SLsmg"? This means that your terminfo databases do not contain the correct definitions for your terminal. You could try using a different terminal setting. If you use csh or tcsh: setenv TERM vt100 or if you use sh, bash, ksh or zsh: export TERM=vt100 4.2 Why don't line drawing characters work? Since version 4.0.13 there's the command line option -a to force use of charaters +, |, - for line drawing (only available when compiled with S-Lang). Use the -a option if any of the suggestions below doesn't help. In general, there are three cases: * Lines are shown as ASCII characters like this +---------+ | | +---------+ This also happens when you use the -a option. Other than that possible reason is 1 or 2 (see below). * Lines are shown as lower case characters like this lqqqqqqqqqk x x mqqqqqqqqqj Possible reason is 1 or 2 (see below). * Lines are shown as blanks or missing characters. Possible reason is 2 or 3 (see below). The reason for the problem is one of following: 1. Your terminal might not support line drawing characters. VT100 compatible terminals, rxvt and xterm and color_xterm do support them. 2. Your terminfo or termcap database might have missing or incorrect definitions for line drawing characters. Set the acsc variable in the terminfo database like this: acsc=a\376k\277l\332m\300j\331n\305w\302v\301u\264t\303q\304x \263h\2600\333 Don't forget issue 'tic' command. This supposes you are using PC character set. The octal values might be different for other character sets. If you are using termcap instead of terminfo, you should modify above solution appropriately. 3. Your terminal font might not support line drawing characters. Try changing the font. Here is Miguel's answer to Torben on this subject. Torben: When I load consolefonts/iso01.f16, I get perfectly right national characters, but the line drawing characters in mc get wrong. Is it a mc problem, or is it a problem with the font? (I guess it is). Is there a trick? Miguel: First of all, we should determine whether the font has line drawing characters or not. If it has line drawing characters, then a new terminfo entry should be written for this specific case. Let's call this linux-iso01. The acsc variable should be modified to reflect which characters are used to do the line drawing. If it does not have line drawing characters, then we should get rid of the switch to acsc sequences and make the acsc sequence be just a mapping to the ugly +, -, |, - characters. You can get your terminfo definition by running the infocmp program, making the proper changes and running the tic program to compile your new terminfo database. 4.3 Can one use latin-1 characters without losing the lines? Yes, you need a correct font and a correct termcap/terminfo database. For font, if you use xterm try "xterm -fn fixed". For termcap/terminfo database, change the acsc capability in the database. 4.4 I have problems with entering/viewing national characters! Upgrade to version 4.0.12 or newer. From the Options - Display Bits dialog select Full 8 bits or ISO 8859-1. In addition, select 8 bit input from the same dialog. 4.5 How can I get colors? Invoke mc like this (without quotes): "mc -c". If you get colors, be happy. If your terminal stays black and white, your terminal doesn't support color. You might want to upgrade to a terminal which compatible with the ANSI color sequences. If your terminal goes completely black, see the next question. More detailed answer: Check that your terminal supports color. color_xterm, rxvt and Linux console do support, most other terminals don't. You can test color support with following simple C program: #include int main (void){ printf ("\033[32m Hello world! \033[m\n"); return 0; } Compile and run it. If you see "Hello world!" text in green your terminal supports color, otherwise not (however, for color_xterm see also the next question). Check whether you are using Ncurses or the S-Lang library (type "mc -V" to find out). With S-Lang library you can force color support by setting the environment variable COLORTERM to any value. If you use ncurses library, check that your terminfo database supports color. If not, you should install one of the enhanced terminfo databases included in GNU Midnight Commander source distribution. You might want to set the TERM environment variable so that you are using the correct terminfo database or termcap entry. If you use color_xterm (or rxvt) the correct value might be xterm-color, xtermc or simply xterm. If you use Linux console the correct value for TERM is linux or console. 4.6 My color_xterm goes completely (or partially) black! Some color_xterm terminals define all colors as black instead of the standard ANSI colors. This makes them go completely black when you try to use Midnight Commander with colors. You will have to override the defaults. Create a file "color.defaults" which has the following contents: color_xterm*color0: Black color_xterm*color1: Red color_xterm*color2: Green color_xterm*color3: Yellow color_xterm*color4: Blue color_xterm*color5: Magenta color_xterm*color6: Cyan color_xterm*color7: White color_xterm*background: White color_xterm*foreground: Black (replace color_xterm with the name of your color_xterm, color_xterm mentions its name in its title bar) Now type: xrdb -merge color.defaults Alternatively you can add the suggested contents of the color.defaults file to your .Xdefaults or .Xresources file (or what ever the name of your X configuration file is). Or you can replace your non-ANSI color_xterm with an ANSI color_xterm. 4.7 Where can I get xterm or rxvt? xterm is included with the X Window System, so you probably already have it if you have X. This version is not actively maintained, but Thomas Dickey maintains his more advanced version of xterm at ftp://dickey.his.com/xterm/ rxvt has its own site http://www.rxvt.org/ - get the latest version there. 4.8 I got colors working with MC but the other programs don't work at all anymore! Midnight Commander uses terminfo database (if available) but many other programs use termcap database. If you set the TERM environment variable to a value which has no corresponding entry in termcap database those programs stop working. You should add the new value of TERM to the termcap database. Example: If you have set TERM to xterm-color locate from /etc/termcap the line which starts: xterm|vs100|xterm terminal emulator Change it to start: xterm|xterm-color|vs100|xterm terminal emulator 5 Graphical user interface 5.1 Xview, Tk and Gnome editions? Xview and Tk and GNOME editions have been removed from the sources. 5.2 Why is MC linked with X libraries? GNU Midnight Commander is linked with X libraries to read key modifiers from the X Server. It may be helpful to distinguish between keys that the terminal emulator reports in the same way, e.g. PgUp and Ctrl-PgUp. Versions of GNU Midnight Commander after 4.6.0 will load X libraries dynamically on the systems that support it. 6 Command line problems 6.1 How do I stay in the last directory when I exit Midnight Commander? See the description of the -P option in the Options section of the manual. 6.2 How can I access command line history? Meta-h shows the last commands you executed from the command line. Duplicates are suppressed from the history. Commands executed from the subshell prompt are not shown. You can put previous commands to the command line with Meta-p. Meta-n moves you forward in history. Since version 4.1.15 all the input widgets have permanent history. You can summon the history listbox by pressing M-h. 6.3 How can I complete commands, file names, variable names and so on? Just press M-Tab. Press M-Tab again to get a listbox if there are multiple possible completions. 6.4 I am using ksh. Can I use functions defined in the .kshrc within MC? Sorry, MC only supports bash, tcsh and zsh functions. Ksh functions are not supported because ksh lacks the necessary hooks needed for subshell integration. Switch to bash or zsh. They are both quite compatible with ksh. Your ksh functions should work as such or after minimal changes. 6.5 Is there any way to include additional options or hot keys to MC? Yes, F2 invokes an user menu, which is fully configurable. You can add any shell commands to the user menu. See the mc(1) man page for more info. Another way to add functionality is the external panelize feature. See the mc(1) man page for more info. And finally, you can code any feature you want yourself. MC source code is free which means you can change it anyway you want. There are some limitations to make sure MC stays free. See GNU General Public License for details. 6.6 When I use Ctrl-O I don't get a subshell. How do I fix this? Only bash, tcsh and zsh can be used as subshell. Use one of those shells as your default shell, and it will be used as subshell in GNU Midnight Commander. 6.7 Ctrl-O doesn't work at all. What happens? Ctrl-O works if either the subshell is used or the terminal can save the output of the commands so it can be restored. If neither is true, there is absolutely nothing interesting behind the panels! Only few terminals support screen saving. It's xterm, rxvt and other xterm-like terminals and virtual terminals on Linux and FreeBSD. 7 Virtual file systems 7.1 How can I see the contents of a tar archive? If you use keyboard just move the selection bar on the tar file and press enter. If you use mouse just double-click on the tar file. The recognized suffixes for tar archives are .tar, .tar.gz and .tgz. You can also enter a tar archive by typing "cd filename#utar" where filename is the name of the archive. In this case, the suffix is not important. 7.2 How do I get out of a tar archive? Just press enter on the toplevel ".." file or change to a non-tar directory. Just typing "cd" with no parameters is enough (it will take you to your home directory). 7.3 How do I do anonymous ftp with MC? Just type "cd ftp://hostname" where hostname is the name of the host you want to connect. Alternatively, select FTP link from the Left or Right menu and type the name of the host you want to connect. 7.4 How do I do non-anonymous ftp with MC? Non-anonymous ftp works just like the anonymous ftp but you give the login name with the host name. For example, type "cd ftp://username@hostname". 7.5 How do I close an ftp connection? Just change to a non-ftp directory. Simply typing "cd" with no parameters is enough (it will take you to your home directory). GNU Midnight Commander closes ftp connection automatically after a timeout or on exit. It's possible to force disconnect by selecting "Command" -> "Active VFS List" in the menu and using the "Free VFSs Now" button. 7.6 Why aren't the contents of ftp panel updated? Update is skipped because there would be a serious performance penalty. Constantly updating directory panels through a ftp connection would take too much time. You can use C-r to force an update. 7.7 What kind of proxy server works with Midnight Commander? There are two kinds of ftp proxies: proxies for ftp clients and proxies for web browsers. Midnight Commander only supports ftp proxies which are meant for ftp clients. Common WWW proxies (like Squid) are not supported. A rule of thumb is that if a ftp proxy requires a web browser, it won't work with Midnight Commander. 8 Other common problems 8.1 When I try pasting to the internal editor, it indents the amount of indenting increases with each line! Either turn off 'Return does autoindent' in the editor options or update GNU Midnight Commander to version 4.6.0 or above - it doesn't autoindent when you are holding Shift. 8.2 Is it possible to use Colorer for syntax highlighting? Yes if you submit the patch. There are no legal problems with it because it's licensed under GPL now. The homepage of Colorer is http://colorer.sourceforge.net/ 9 Other common problems 9.1 Is there any way to 'bookmark' favorite ftp-fs links? Use the directory hotlist. Just press control-backslash. If your national keyboard layout doesn't have backslash key, just press the control key with the key which is the backslash key in the English keyboard layout. 9.2 When I start Midnight Commander, nothing happens! When MC is compiled with Samba support, have a look at the "interfaces = ..." line in your smb.conf file. MC uses pretty old Samba code that only expects IP addresses and host names there, but not network interface names (like eth0). MC interprets these names as host names and tries to resolve them using a DNS server. To fix this, ask your system administrator to change the interface names to their assigned IP addresses, or (untried) add the interface names and their IP addresses to the /etc/hosts file. First, invoke MC without subshell support: "mc -u". If this helps check the shell you are using. Subshell support works best with bash, although tcsh and zsh are also supported. You might want to upgrade your shell to a newer version. If you use something else than bash, tcsh or zsh, subshell support is disabled automatically. Another reason is problems with gpm. Try using "--nomouse" option to see if it makes any difference. Restarting gpm can help. Sometimes it's enough to move the mouse. Also, if you have the DISPLAY environment variable set, but the X server is unreachable (e.g. it's firewalled), this can also cause a delay at startup. Unset DISPLAY to see if that's the case. 10 Development 10.1 Who has written Midnight Commander? Midnight Commander was started by Miguel de Icaza and he is the maintainer of the package. Other authors have joined the project later: * Mauricio Plaza (early releases) * Janne Kukonlehto (joined Sep 27 1994) * Radek Doulik (joined Oct 30 1994) * Fred Leeflang (joined Nov 2 1994) * Dugan Porter (joined Dec 1 1994) * Jakub Jelinek (joined Feb 8 1995) * Ching Hui (joined Jun 27 1995) * Andrej Borsenkow (joined Jul 1996) * Paul Sheer (joined Nov 1 1996) * Norbert Warmuth * Alex I. Tkachenko Alessandro Rubini has been specially helpful with debugging and enhancing of the mouse support. John E. Davis has made his S-Lang library available to us and answered many questions about it. Many people have contributed bug reports, feature suggestions and small code bits (alphabetical order): * Thomasz Cholewo * Juan Jose Ciarlante * Alexander Dong (OS/2 port, NT port updates) * Erwin van Eijk * Torben Fjerdingstad * Massimo Fontanelli * Juan Grigera (NT port) * Gerd Knorr * Sergey Ya. Korshunoff * Jean-Daniel Luiset * Wim Osterholt * Antonio Palama (old DOS port) * Thomas Pundt * Marcelo Roccasalva * Ilya Rybkin * Vadim Sinolits * Jon Stevens * Adam Tla/lka Current list of active developers can be found here: http://www.midnight-commander.org/wiki/McDevelopers This page lists everbody who has provided a patch or has written code for the midnight-commander in the past: http://www.midnight-commander.org/wiki/McContributors 10.2 Do I dare to use a development version? Yes, of course. Feel free to test: http://www.midnight-commander.org/wiki#Download As we do our development in git, please do a git checkout of the master branch and build it But always remember: development versions may have nasty bugs at some points of time. It's up to you to judge whether the new features and fixes for the bugs you know outweigh the risk of unknown bugs. 10.3 How can I report a bug/request for a feature? You might first want to get the newest development version to see if the bug is fixed or the feature is added already. If this is not the case, feel free to add a ticket in our ticket-system, which is located here: http://www.midnight-commander.org/newticket If you want to send an email instead write your report to mc-devel@gnome.org or mc@gnome.org. These mailing lists are the most certain way to contact the developers. Remember to mention if you are not on the mailing list to make sure that you will receive a copy of replies. Give as much details as possible. A too long message is a lot better than a too short message. For segmentation faults a stack backtrace is appreciated. You can produce stack backtrace as follows: * If segmentation fault produced a core file: 1. Load the core file by typing "gdb mc core" or "dbx mc core". 2. Type "where". 3. Cut and paste the results to your message. * If segmentation fault didn't produce a core file: 1. Load mc by typing "gdb mc" or "dbx mc". 2. Start mc by typing "run". 3. Try to reproduce the segmentation fault by doing whatever you did last time when the segmentation fault occurred. 4. Type "where". 5. Cut and paste the results to your message. 6. For the future you might want to check out what is the command in your shell to allow producing of the core files. Usually it is "limit coredumpsize unlimited" or "ulimit coredumpsize" or "ulimit -c unlimited". 10.4 How can I join the development? To join the development just code the feature you want to add and send your patch for inclusion. Email address is mc-devel@gnome.org. Before you start coding check the latest development version. It might be that your feature has already been implemented. Note that the authors of GNU Midnight Commander have given all their rights on the program to the Free Software Foundation. You will have to do the same if you contribute non-trivial patches. Otherwise we have to reject your patches in order to avoid copyright problems. 11 More information 11.1 This document didn't answer my question. Where else can I look for an answer? Read messages from the Discussion (mailing list archive) or read the Manual. Upgrade to a newer version of Midnight Commander. Many problems are fixed in the new versions. If you still can't find an answer, post your question to the Midnight Commander mailing list. Its address is mc@gnome.org. 11.2 What mailing lists are there for Midnight Commander? Following mailing lists discuss about Midnight Commander: mc@gnome.org General discussion of GNU Midnight Commander To subscribe visit http://mail.gnome.org/mailman/listinfo/mc/ mc-devel@gnome.org Technical development discussion To subscribe visit http://mail.gnome.org/mailman/listinfo/mc-devel/ mc-commits@googlegroups.com mailing list only for applyed commits into master/stable branches To subscribe visit http://groups.google.com/group/mc-commits/subscribe mc-bugs@googlegroups.com Mailing list only for tickets and comments (use it as RSS :) ) To subscribe visit http://groups.google.com/group/mc-bugs/subscribe 11.3 Where should I look on the World Wide Web for MC stuff? There is a WWW page for Midnight Commander. The URL is: http://www.midnight-commander.org/ 11.4 Are the mailing lists archived anywhere? The mc and mc-devel lists are archived on the World Wide Web. There are links to the archives on the mailing list pages (see 10.2). 12 Legal issues 12.1 Authorship Questions and Answers was written by Janne Kukonlehto. Parts of it originate from Ian Jackson, Miguel de Icaza, Dugan Porter, Norbert Warmuth and Paul Sheer. 12.2 Feedback is invited Send your comments about this document and GNU Midnight Commander to mc@gnome.org 12.3 Disclaimer and copyright Note that this document is provided as is. The information in it is not warranted to be correct; you use it at your own risk. You can use Questions and Answers according to GNU General Public License (see the COPYING file in GNU Midnight Commander source distribution). Questions and Answers is not public domain. usr/share/doc/net-snmp/FAQ000064400000517105152532304620011332 0ustar00 Frequently Asked Questions (FAQ) for the UCD/Net-SNMP package ============================================================= FAQ Author: Dave Shield Net-SNMP Version: 5.8 Net-SNMP/UCD-SNMP Project Leader: Wes Hardaker Email: net-snmp-coders@lists.sourceforge.net TABLE OF CONTENTS ================= TABLE OF CONTENTS GENERAL What is it? Where can I get it? What documentation is available? Are there binaries available? What's the difference between UCD-SNMP and Net-SNMP? What operating systems does it run on? What happens if mine isn't listed? Does it run on Windows? How do I find out about new releases? How can I find out what other people are doing? How do I submit a patch or bug report? Can I reuse the code in my commercial application? What's the difference between SNMPv1, SNMPv2 and SNMPv3? What's the difference between SNMPv2 and SNMPv2c? Which versions of SNMP are supported in this package? Can I use SNMPv1 requests with an SNMPv2 MIB (or vice versa)? How can I monitor my system with SNMP? Where can I find more information about network management? What ports does SNMP use? Is Net-SNMP thread safe? APPLICATIONS How do I add a MIB? How do I add a MIB to the tools? Why can't I see anything from the agent? Why doesn't the agent respond? I can see the system group, but nothing else. Why? Why can't I see values in the tree? The agent worked for a while, then stopped responding. Why? Requesting an object fails with "Unknown Object Identifier" Why? Why do I get "noSuchName" when asking for "sysUpTime" (or similar)? Why do I sometimes get "End of MIB" when walking a tree, and sometimes not? How do I use SNMPv3? Why can't I set any variables in the MIB? Variables seem to disappear when I try to set them. Why? Why can't I change sysLocation (or sysContact)? I get an error when trying to set a negative value - why? I get an error when trying to query a string-indexed table value - why? How should I specify string-indexed table values? How do I send traps and notifications? How do I receive traps and notifications? How do I receive SNMPv1 traps? Why don't I receive incoming traps? My traphandler script doesn't work when run like this - why not? How can the agent receive traps and notifications? How big can an SNMP request (or reply) be? How can I monitor my systems (disk, memory, etc)? Applications complain about entries in your example 'snmp.conf' file. Why? OK, what should I put in snmp.conf? How do I specify IPv6 addresses in tools command line arguments? PERL What is the purpose of the Perl SNMP module? Where can I get the Perl SNMP package? How do I install the Perl SNMP modules? But compiling this fails! Why? Compiling the Perl module works OK, but 'make test' fails. Why? Why can't mib2c (or tkmib) locate SNMP.pm? Why can't mib2c (or tkmib) load SNMP.so? Why can't tkmib locate Tk.pm? Why does your RPM complain about missing Perl modules? I've got a problem with the Net-SNMP module. Can you help? MIBS Where can I find a MIB compiler? Why aren't my MIB files being read in? Where should I put my MIB files? What does "Cannot find module (XXX-MIB)" mean? I'm getting answers, but they're all numbers. Why? What does "unlinked OID" mean? The parser doesn't handle comments properly. Why not? How can I get more information about problems with MIB files? What's this about "too many imported symbols"? Do I actually need the MIB files? AGENT What MIBs are supported? What protocols are supported? How do I configure the agent? How do I remove a MIB from the agent? I've installed a new MIB file. Why can't I query it? How do I add a MIB to the agent? What's the difference between 'exec', 'sh', 'extend' and 'pass'? What's the difference between AgentX, SMUX and proxied SNMP? What is the purpose of 'dlmod'? Which should I use? Can I use AgentX when running under Windows? How can I run AgentX with a different socket address? How can I turn off SMUX support? How can I combine two copies of the 'mib2' tree from separate subagents? What traps are sent by the agent? Where are these traps sent to? How can I send a particular trap to selected destinations? When I run the agent it runs and then quits without staying around. Why? After a while the agent stops responding, and starts eating CPU time. Why? How can I stop other people getting at my agent? How can I listen on just one particular interface? The agent is complaining about 'snmpd.conf'. Where is this? Why does the agent complain about 'no access control information'? How do I configure access control? How do I configure SNMPv3 users? The 'createUser' line disappears when I start the agent. Why? What's the difference between /var/net-snmp and /usr/local/share/snmp? My new agent is ignoring the old snmpd.conf file. Why? Where should the snmpd.conf file go? Why am I getting "Connection refused"? Why can't I see values in the UCDavis 'extensible' or 'disk' trees? Why can't I see values in the UCDavis 'memory' or 'vmstat' tree? What do the CPU statistics mean - is this the load average? How do I get percentage CPU utilization using ssCpuRawIdle? What about multi-processor systems? The speed/type of my network interfaces is wrong - how can I fix it? The interface statistics for my subinterfaces are all zero - why? Does the agent support the RMON-MIB? What does "klread: bad address" mean? What does "nlist err: wombat not found" (or similar) mean? What does "Can't open /dev/kmem" mean? The system uptime (sysUpTime) returned is wrong! Can the agent run multi-threaded? Can I use AgentX (or an embedded SNMP agent) in a threaded application? COMPILING How do I control the environment used to compile the software? How do I control the environment used to compile the software under Windows? Why does the compilation complain about missing libraries? How can I reduce the memory footprint? How can I reduce the installation footprint or speed up compilation? How can I compile the project for use on an embedded system? How can I compile the project to use static linking? Why does 'make test' skip various tests? Why does 'make test' complain about a pid file? CODING How do I write C code to integrate with the agent? How does the agent fetch the value of a MIB variable from the system? Mib2c complains about a missing "mib reference" - what does this mean? Mib2c complains about not having a "valid OID" - what does this mean? Why doesn't mib2c like the MIB file I'm giving it? Mib2c ignores my MIB and generates a pair of 'mib-2' code files. Why? What's the difference between the various mib2c configuration files? Which mib2c configuration file should I use? How can I have mib2c generate code for both scalars and tables? Are there any examples, or documentation for developing MIB modules? Where should I put the files produced by 'mib2c'? Why doesn't my new MIB module report anything? Why does the iterator call my get_{first,next} routines so often? How can I get the agent to generate a trap (or inform)? How can I get an AgentX sub-agent to generate a trap (or inform)? How can I get the agent to send an SNMPv1 (or SNMPv2c) trap? How can I get the agent to include varbinds with an SNMPv1 trap? How can I get the agent to send an SNMPv1 enterprise-specific trap? How can I get the agent to send an SNMPv3 trap (or inform)? Why does calling 'send_v2trap' generate an SNMPv1 trap (or vice versa)? How can I register a MIB module in a different (SNMPv3) context? MISC What ASN.1 parser is used? What is the Official Slogan of the net-snmp-coders list? GENERAL ======= What is it? ---------- - Various tools relating to the Simple Network Management Protocol including: * An extensible agent * An SNMP library * tools to request or set information from SNMP agents * tools to generate and handle SNMP traps * a version of the unix 'netstat' command using SNMP * a graphical Perl/Tk/SNMP based mib browser This package is originally based on the Carnegie Mellon University SNMP implementation (version 2.1.2.1), but has developed significantly since then. Where can I get it? ------------------ Download: - http://www.net-snmp.org/download/ Web page: - http://www.net-snmp.org/ Sourceforge Project page: - http://www.net-snmp.org/project/ Mirrors (note that sourceforge download servers are mirrored themselves): - Greece: ftp://ftp.ntua.gr/pub/net/snmp/net-snmp/ What documentation is available? ------------------------------- This FAQ (!) README and individual READMEs for various platforms README.thread (discusses threading issues) INSTALL PORTING EXAMPLE.conf man pages for the individual tools, files and the API A guide for extending the agent Tutorials for both ucd-snmp v4 and net-snmp v5 at http://www.net-snmp.org/tutorial/ and http://www.net-snmp.org/tutorial-5/ respectively Most of this documentation (plus archives of the mailing lists) is also available on our web page: http://www.net-snmp.org/ There is also a Wiki (including a community-maintained version of this FAQ) at http://www.net-snmp.org/wiki/ Are there binaries available? ---------------------------- There are binaries for some versions/systems available under the "net-snmp binaries" package on the SourceForge "Files" page, which is linked to from the main project download web page at http://www.net-snmp.org/download.html. These binaries are also available on the project FTP site, with a link on the same web page. What's the difference between UCD-SNMP and Net-SNMP? --------------------------------------------------- Not a great deal, really. Although the project originally started at UC Davis (hence the name), and it has always been based there, most of the contributors have had little or no connection with this institution. The move to SourceForge was intended to provide a more flexible environment for the project, and to distribute the administrative workload more evenly. The change of name simply reflects this move, which was the last remaining link with UC Davis. The 4.2.x line saw the last releases made using the ucd-snmp name, and all releases on this line have been been bug-fixes only. Release 5.0 was the first version released under the Net-SNMP name, and all further development is being done on the 5.x code base. The 4.2.x code line is now effectively closed down, as are the older 5.x branches. Much of the work done for the various 5.x releases has involved some fairly significant changes to the code - in particular the architecture of the agent. However attempts have been made to retain backwards compatibility as much as possible, and most code written for earlier releases should continue to work. The most visible change from the 4.2.x UCD suite to the 5.x Net-SNMP releases was a restructuring of the header file organisation - not least a change from to . But given the maturity of the Net-SNMP code, this should be less of a consideration for most current SNMP development projects. What operating systems does it run on? ------------------------------------- Both the applications and the agent have been reported as running (at least in part) on the following operating systems: * Linux (kernels 2.6 to 1.3) * Solaris/SPARC (11 to 2.3), Solaris/Intel (10, 9) -- see README.solaris * HP-UX (11.31 to 9.01) -- see README.hpux11 * Mac OS X (10.5 to 10.1) -- see README.osX * NetBSD (2.0 to 1.0) * FreeBSD (7.0 to 2.2) * OpenBSD (4.0 to 2.6) * BSDi (4.0.1 to 2.1) * AIX (6.1, 5.3, 5.2, 5.1, 4.3.3, 4.1.5, 3.2.5) -- see README.aix * IRIX (6.5 to 5.1) * OSF (4.0, 3.2 and Tru64 Unix 5.1B) -- see README.tru64 * SunOS 4 (4.1.4 to 4.1.2) * Ultrix (4.5 to 4.2) * Dynix/PTX 4.4 * QNX 6.2.1A We have also been informed about a port to the Stratus VOS. See http://ftp.stratus.com/vos/network/network.html for details. See the next question but one for the status of Windows support. Certain systems fail to compile particular portions of the agent. These can usually be persuaded to compile (at the loss of some functionality) by omitting the modules affected. See the next question for more details. Also note that the presence of a particular configuration in this list does not imply a perfect or complete implementation. This is simply what various people have reported as seeming to work. (Or more frequently, the configurations where people have reported problems that we think we've subsequently fixed!) What happens if mine isn't listed? --------------------------------- It's probably worth trying to compile it anyway. Unless your system is significantly different to the supported configurations, most of the code (library, applications and the agent infrastructure) should probably compile with little or no difficulty. The most likely source of problems will be MIB modules within the agent, as this tends to be where the most system-specific code is found. If only a few modules fail to compile, try removing them from the agent by running "configure --with-out-mib-module=xxx,yyy", and re-compiling. If a large number of modules fail, then it might be easier to start from a relatively bare system, using "configure --enable-mini-agent --with-defaults". Then if this minimal agent compiles and runs successfully, try adding each of the missing mibgroups individually using the configure option '--with-mib-module'. If configure fails with "invalid configuration" messages, or you get completely stuck, contact the coders list for advice. Similarly, if you manage to get this working on a new system, please let us know of any code changes that you needed to make, together with details of the hardware you're using, and what versions of the operating system you've tried it on. The entry 'host' in the file 'config.status' should show this information. Oh, and congratulations! Does it run on Windows? ---------------------- The suite should compile and run on Win32 platforms, including the library, command-line tools and the basic agent framework. Note that the agent now includes support for the MIB-II module, but this requires Microsoft's Core Platform SDK. Instructions for how to install this are given in README.win32. Pre-compiled binaries are available from the project web site. As of v5.4, the Net-SNMP agent is able to load the Windows SNMP service extension DLLs by using the Net-SNMP winExtDLL extension. Some other Net-SNMP MIB modules, including the UCD pass-through extensions, do not currently work under Windows. Volunteers to assist with these missing modules are likely to welcomed with open arms :-) Further details of Windows support (currently Visual C++, MinGW and Cygnus cygwin32) is available in the file README.win32. How do I find out about new releases? ------------------------------------ There is a mailing list for these announcements net-snmp-announce@lists.sourceforge.net To be added to (or removed from) this list, visit http://www.net-snmp.org/lists/net-snmp-announce/ Or you can send a message to the address net-snmp-announce-request@lists.sourceforge.net with a subject line of 'subscribe' (or 'unsubscribe' as appropriate). Advance notice of upcoming releases are also made on the net-snmp-users list (for "release candidates") for a week or two before the full release, and on the net-snmp-coders list (for "pre-releases") during the period prior to this. Major code revisions may be announced more widely, but these lists are the most reliable way to keep in touch with the status of the package. Patches to fix known problems are also made available via the web site: http://www.net-snmp.org/patches/ How can I find out what other people are doing? ---------------------------------------------- There is a general purpose discussion list net-snmp-users@lists.sourceforge.net To be added to (or removed from) this list, visit http://www.net-snmp.org/lists/net-snmp-users/ Or you can send a message to the address net-snmp-users-request@lists.sourceforge.net with a subject line of 'subscribe' (or 'unsubscribe' as appropriate). To find out what the developers are doing, and to help them out, please read the PORTING file enclosed with the package. There is also a #net-snmp IRC channel set up on the freenode.net chat system. You can connect to this via chat.freenode.net. See http://www.freenode.net/ for more information on getting started with IRC. Several core developers hang out on this channel on a fairly regular basis. How do I submit a patch or bug report? ------------------------------------- The best way to submit a bug report is via the bug database through the interface found at http://www.net-snmp.org/bugs/ Be sure to include the version of the package that you've been working with, the output of the command 'uname -a', the precise configuration or command that triggers the problem and a copy of any output produced. Questions about using the package should be directed at the net-snmp-users@lists.sourceforge.net mailing list. Note that this mailing list is relatively busy, and the people answering these questions are doing so out of the goodness of their hearts, and in addition to their main employment. Please note the following: - use plain text mail, rather than HTML - don't resend questions more than once (even if no-one answered immediately) - include full details of exact commands and error messages ("I've tried everything, and it doesn't work" isn't much use!) - do *NOT* send messages to -users and -coders mailing lists (most developers read both anyway) - don't mail the developers privately - keep everything on the list We can't promise to be able to solve all problems, but we'll certainly try and help. But remember that this is basically an unsupported package. It's Open Source, so if you need something fixing badly enough, fundamentally it's up to you to do the work. All patches should be submitted to the patch manager at http://www.net-snmp.org/patches/ If possible, submit a bug report describing the patch as well (referencing it by its patch number) since the patch manager doesn't contain a decent description field. The best way to submit patch (diff) information is by checking out the current code from the development git trunk, making your changes and then running "git diff" or "git format-patch" after you're done. (Please see http://www.net-snmp.org/wiki/index.php/Git for further information on using git with the Net-SNMP project) If you're working from a source code distribution, and comparing old and new versions of a code file, use "diff -u OLDFILE NEWFILE" Can I reuse the code in my commercial application? ------------------------------------------------- The details of the COPYRIGHTs on the package can be found in the COPYING file. You should have your lawyer read this file if you wish to use the code in your commercial application. We will not summarize here what is in the file, as we're not lawyers and are unqualified to do so. What's the difference between SNMPv1, SNMPv2 and SNMPv3? ------------------------------------------------------- What's the difference between SNMPv2 and SNMPv2c? ------------------------------------------------ A full description is probably beyond the scope of this FAQ. Very briefly, the original protocol and admin framework was described in RFCs 1155-1157, and is now known as SNMPv1. Practical experience showed up various problems and deficiencies with this, and a number of revised frameworks were developed to try and address these problems. Unfortunately, it proved difficult to achieve any sort of agreement - particularly over the details of the administrative framework to use. There was less disagreement over the proposed changes to the protocol operations. These included: * increasing the range of errors that could be reported * introducing "exception values" (so a single missing value didn't affect the other varbinds in the same request) * a new GETBULK operation (a supercharged GETNEXT) * new notification PDUs (closer in structure to the other request PDUs) Strictly speaking, it's this revised protocol (originally defined in RFC 1905, and most recently in RFC 3416) that is "SNMPv2". The only framework based on this protocol that saw a significant level of use was "Community-based SNMPv2" or "SNMPv2c" (defined in RFC 1901). This retained the same administrative framework as SNMPv1 (with all of the accompanying limitations), but using the new protocol operations. More recently, a new administrative framework has been developed, building on the various competing SNMPv2 proposals, and using the same SNMPv2 protocol operations. This is SNMPv3, which is defined in RFCs 3411-3418. It addresses some of the deficiencies of the community-based versions, including significant improvements to the security of SNMP requests (like it finally has some!). SNMPv3 is now a full IETF standard protocol. Strictly speaking, SNMPv3 just defines a fairly abstract framework, based around the idea of "Security Models" and "Access Control Models". It's this combination of SNMPv3 plus accompanying models that actually provides a working SNMP system. However, the only models in common use are the "User-based Security Model" (RFC 3414) and the "View-based Access Control Model" (RFC 3415). So "SNMPv3" is frequently used to mean the combination of the basic SNMPv3 framework with these two particular models. This is also sometimes described as "SNMPv3/USM". So in brief: - SNMPv2c updated the protocol operations but left the administrative framework unchanged. - SNMPv3 updated the administrative framework but left the protocol operations unchanged. Which versions of SNMP are supported in this package? ---------------------------------------------------- This package currently supports the original SNMPv1 (RFC 1157), Community-based SNMPv2 (RFCs 1901-1908), and SNMPv3 (RFCs 3411-3418). The agent will respond to requests using any of these protocols, and all the tools take a command-line option to determine which version to use. Support for SNMPv2 classic (a.k.a. "SNMPv2 historic" - RFCs 1441-1452) was dropped with the 4.0 release of the UCD-snmp package. Can I use SNMPv1 requests with an SNMPv2 MIB (or vice versa)? ------------------------------------------------------------ Yes. The syntax used to specify a MIB file (better referred to as SMIv1 or SMIv2) is purely concerned with how to define the characteristics of various management objects. This is (almost) completely unrelated to the versions of the protocol used to operate on these values. So it is quite reasonable to use SNMPv1 requests on objects defined using SMIv2, or SNMPv2 (or SNMPv3) requests on objects defined using SMIv1. The one exception is objects of syntax Counter64, which are only accessible using SNMPv2 or higher. SNMPv1 requests will either treat such objects as an error, or skip them completely. Note that SMIv1 is effectively obsolete, and all new MIBs should be written using SMIv2. How can I monitor my system with SNMP? ------------------------------------- There are two main methods of using SNMP for monitoring. One is to regularly query the SNMP agent for information of interest, graphing these values and/or saving them for later analysis. That's not really the focus of the Net-SNMP project - our tools are more low-level, single-shot commands. For this sort of high-level management, you're really looking at a management console application (such as Nagios or OpenNMS), or a data logging application (such as RRDtool, or one of its front-ends - MRTG, Cacti, etc). The other approach is to configure the SNMP agent to monitor the relevant information itself, and issue an alert when the values pass suitable limits. See the section ACTIVE MONITORING in the snmpd.conf(5) man page for details. Note that this entry makes no reference as to _what_ you should monitor, or what values might be significant. That's because it is impossible to provide a universal answer to these questions. The information to monitor, and the normal operating values will ultimately depend on your local environment. SNMP is simply a tool to _help_ you manage your systems - it isn't a magic panacea - you still have to think for yourself! Where can I find more information about network management? ---------------------------------------------------------- There are a number of sites with network management information on the World Wide Web. Some of the most useful are http://www.simpleweb.org/ http://www.snmplink.org/ http://www.mibdepot.com/ The SNMP Usenet newsgroup is now mostly defunct, but although the FAQ hasn't been updated for a while, it still contains a large amount of useful information relating to SNMP, including books, software, other sites, how to get an enterprise number, etc, etc. This is available from ftp://rtfm.mit.edu/pub/usenet/comp.protocols.snmp/ or via any of the Web sites above. What ports does SNMP use? ------------------------ There are three main network ports (and one named socket), which are typically used by SNMP. These are: - UDP port 161 - SNMP requests (GET* and SET) - UDP port 162 - SNMP notifications (Traps/Informs) - TCP port 705 - AgentX - /var/agentx/master - AgentX However, these are simply the default "well-known" ports for these purposes, and it is perfectly possible to accept requests on other ports. Is Net-SNMP thread safe? ----------------------- Strictly speaking, no. However, it is possible to use the library within a multi-threaded management application. This is covered in detail in the file README.thread (shipped with the standard distribution), but can be summarised as follows: - Call 'snmp_sess_init()' prior to activating any threads. This reads in and parses MIB information (which isn't thread-safe) as well as preparing a session structure for subsequent use. - Open an SNMP session using 'snmp_sess_open()' which returns an opaque session handle, which is essentially independent of any other sessions (regardless of thread). - Resource locking is not handled within the library, and is the responsibility of the main application. The Net-SNMP agent has not been designed for multi-threaded use. It should be safe to use the agent library to embed a subagent within a threaded application as long as *all* SNMP-related activity (including generating traps, and parsing MIBs) is handled within a single thread. The command-line tools shipped as part of the Net-SNMP distribution are simple single-threaded applications, and are not designed for multi-threaded use. Adapting these to a threaded model is left as an exercise for the student. The same holds true for the notification receiver (snmptrapd). Unfortunately, the SNMPv3 support was added about the same time as the thread support and since they occurred in parallel the SNMPv3 support was never checked for multi-threading correctness. It is most likely that it is not thread-safe at this time. APPLICATIONS ============ How do I add a MIB? ------------------ This is actually two separate questions, depending on whether you are referring to the tools, or the agent (or both). See the next question or the next section respectively. How do I add a MIB to the tools? ------------------------------- Adding a MIB to the client-side tools has two main effects: - it allows you to refer to MIB objects by name (rather than having to use the numeric OIDs) - it allows the results to be displayed in a more immediately meaningful fashion. Not just giving the object names, but also showing named enumeration values, and interpreting table indexes properly (particularly for string and OID index values). There are two steps required to add a new MIB file to the tools. Firstly, copy the MIB file into the appropriate location: cp MY-MIB.txt /usr/local/share/snmp/mibs (which makes it available to everyone on the system) or mkdir $HOME/.snmp mkdir $HOME/.snmp/mibs cp MY-MIB.txt $HOME/.snmp/mibs (which makes it available to you only) Note that the location of the shared MIB directory may be different from that given here - see the FAQ entry "Where should I put my MIB files?" for more information. Secondly, tell the tools to load this MIB: snmpwalk -m +MY-MIB ..... (load it for this command only) or export MIBS=+MY-MIB (load it for this session only) or echo "mibs +MY-MIB" >> $HOME/.snmp/snmp.conf (load it every time) Note that the value for this variable is the name of the MIB module, *not* the name of the MIB file. These are typically the same (apart from the .txt suffix), but if in doubt, check the contents of the file. The value to use is the token immediately before the word DEFINITIONS at the start of the file. Or use the special value "all" to have the tools load all available MIBs (which may slow them down, particularly if you have a large number of MIB files. Note that you need *both* steps. Adding a MIB in this way does *not* mean that the agent will automatically return values from this MIB. The agent needs to be explicitly extended to support the new MIB objects, which typically involves writing new code. See the AGENT section for details. Most of the tools (apart from 'snmptable') will work quite happily without any MIB files at all - although the results won't be displayed in quite the same way. Similarly, the agent doesn't need MIB files either (other than to handle MIB object names in the configuration file). Why can't I see anything from the agent? --------------------------------------- Fundamentally, there are two basic reasons why a request may go unanswered. Either the management application does not like the request (so never sends it), or the agent does not like the request (so never responds). The simplest way to distinguish between the two is to run the command with the command-line option '-d'. If this doesn't display a hex dump of the raw outgoing packet, then it's the client side which is dropping the request. Hopefully you should also see an error message, to help identify what's wrong. If this displays one or more outgoing dumps (but nothing coming back), then the request is failing at the agent end. See the next entry for more details. There are three further possibilities to consider: One is that the agent may return a response to the original query, but the management application may not like this response, and refuse to display it. This is relatively unusual, and typically indicates a flaw with the remote agent. (I hope you're not contemplating the suggestion that the Net-SNMP command-line tools might contain bugs!) The typical symptoms of this would be that the '-d' option would display a sequence of sending and received packet dumps, with the same contents each time. Ask on the mailing list for advice. Alternatively, the agent may simply not support the MIB objects being requested. This is most commonly seen when using the "snmpwalk" tool (particularly with SNMPv1). The symptoms here would be that '-d' would show two pairs of raw packet dumps - one a GETNEXT request (A1 in the sending packet), followed by a GET request (A0). Repeating the same request with the "snmpgetnext" command-line tool should show the information (if any) that the agent returned, which was then discarded by snmpwalk as irrelevant. Note that this is how snmpwalk was designed to work. It is not an error. Finally, it may be that the agent is simply taking too long to respond. The easiest way to test for this is to add the command-line options "-t 60 -r 0", which will send a single request (with no repetitions) and wait for a minute before giving up. This ought to be long enough for all but the most-overloaded agent, or inefficient MIB module! If this turns out to be the cause, then ask on the mailing list for advice on options for improving the performance. Why doesn't the agent respond? ----------------------------- Assuming that the tests outlined in the previous entry indicate that the problem lies with the agent not responding, the obvious question is "why not". Again, there are two basic possibilities - either the agent never sees the request, or it receives it but is unwilling (or unable) to process it. If the remote system is running the Net-SNMP agent, then the easiest way to distinguish between these two cases is to shut down the agent, and re-start it manually using the options -f -Le -d Then send the same query as before. This should display raw dumps of packets seen (or sent) by the agent, just as with the client side in the previous entry. If the agent does not display anything, then it is simply not receiving the requests. This may be because they are being blocked by network or local firewall settings ('iptables -L'), or the agent may not be listening on the expected interfaces ('netstat -a'). This is most commonly encountered when running queries from a remote host, particularly if the same request succeeds when run on the same system as the agent itself. If the agent displays a dump of the incoming request, but nothing going out, then the most likely cause is access control settings. See the relevant entries in the AGENT section for details. Note that if the agent receives an SNMPv1 or SNMPv2c request with a unknown community string, then it will not return an error response - the request is simply discarded. Another possibility is that the request may be rejected by settings in /etc/hosts.{allow,deny}. Again, '-d' will display an incoming packet dump but no corresponding outgoing response. However in this situation, the agent should also log a message that the request is being refused. Running the agent with '-d' can also help identify situations where the agent *is* responding to the request, but only after a long delay. This would be indicated by a series of incoming packet dumps (showing various retries from the client side), followed by several outgoing dumps - possibly long after the client tool has given up in disgust. See the entry The agent worked for a while, then stopped responding. Why? later in this section. I can see the system group, but nothing else. Why? -------------------------------------------------- This is almost definitely due to the access configuration of the agent. Many pre-configured systems (such as most Linux distributions) will only allow access to the system group by default, and need to be configured to enable more general access. The easiest way to test this is to try a GETNEXT request on one of the other standard groups e.g. snmpgetnext ..... interfaces If the agent responds with "hrSystemUptime.0" or "end of MIB", then it is clearly configured in this way. See the entries on access control in the AGENT section for more information. Why can't I see values in the tree? ----------------------------------------------- If you can see most of the standard information (not just the system and hrSystem groups), but not in the vendor-specific 'enterprises' tree, then once again there are several possible causes. Firstly, it's possible that the agent does not implement this particular enterprise tree. Remember that adding a MIB to the client tools does *not* automatically add support for these object to the agent. See the AGENT section for more information. Alternatively, it may be that the agent does implement some or all of this enterprise tree, but the access control settings are configured to block access to it. The simplest way to checks whether the agent implements a given portion of the OID tree is to run snmpwalk .... nsModuleName and look for index values that fall in the area of interest. (Always assuming that you have access to this particular section of the Net-SNMP enterprise tree, of course!) Checking the access control settings can be done by examining the tables vacmAccessTable and vacmViewTreeFamilyTable. Note that these are used to configure access control for *all* versions of SNMP - not just SNMPv3. The third possibility is that simply isn't any information in the specified tree. For example, several of the tables in the UCDavis enterprise tree (such as prTable, extTable, dskTable and fileTable) require explicit configuration in the snmpd.conf file. If you query this particular tables without the necessary configuration entries, then they will be empty. Finally, if you can't see anything from *any* enterprise-specific tree, then this may be down to how you are asking for the information. By default, if "snmpwalk" is run without an explicitly starting OID, then it will display the contents of the 'mib-2' tree, containing most of the IETF-standard management information supported by the agent. When the agent reaches the end of this tree, it will return the first enterprise-specific value, 'snmpwalk' will recognise that this marks the end of the (implicit) requested tree, and stop. No enterprise-specific information will be displayed. To walk the whole tree, and see *all* the information that the agent supports, specify a starting point of '.iso' or '.1'. To walk a specific enterprise subtree, specify the root of this tree as the starting point - e.g: snmpwalk -v1 -c public localhost UCD-SNMP-MIB::ucdavis There is more information about particular UCD-specific subtrees in the AGENT section. The agent worked for a while, then stopped responding. Why? ----------------------------------------------------------- There are three basic possibilities: - the agent has crashed - it is hanging - it is temporarily overloaded Detecting whether the agent has crashed should be fairly straighforward. If you can reliably reproduce this crash (e.g. by sending a particular SNMP request), then contact the coders list for advice. It's the other two cases that are probably more significant. To tell the difference between these two, try leaving the agent undisturbed for a while, and then probe it using a single 'snmpget' request, specifying a longer timeout (e.g. '-t 120'). If it now responds, then something was probably sending requests (including duplicate retries) faster than the agent could process them, and it was building up a backlog. Try adjusting the timeout period and retry frequency of these client requests, or look at improving the efficiency of the implementation of the relevant MIB objects. If the agent remains unresponsive (particularly if the load on the system is steadily climbing), then it's probably hanging, and all you can really do is restart the agent. If you can identify what causes this to happen, then contact the coders list for advice. Requesting an object fails with "Unknown Object Identifier" Why? ---------------------------------------------------------------- If a general snmpwalk shows a particular entry, but asking for it more specifically gives a "sub-identifier not found:" or "Unknown Object Identifier" error, then that's a problem with the tool, rather than the agent. Firstly, make sure that you're asking for the object by the right name. Object descriptors are case-sensitive, so asking for 'sysuptime' will not be recognised, but 'sysUpTime' will. Alternatively, the object may be defined in a MIB that hasn't been loaded. Try loading in all the MIB files: snmpget -m ALL -v1 -c public localhost sysUpTime.0 or specify the name of the appropriate MIB explicitly: snmpget -v1 -c public myhost SNMPv2-MIB::sysUpTime.0 Note that this uses the name of the *module*, not the name of the file. However, if 'snmpwalk' displays the object by name, this is unlikely to be the cause, and you should look closely at the exact object name you are using. In particular, see the next entry. Why do I get "noSuchName" when asking for "sysUpTime" (or similar)? ------------------------------------------------------------------ Assuming that you do have access to this object, the most likely cause is forgetting the instance subidentifier. If you try walking the 'system' group (or any other part of the MIB tree), you should notice that all of the results have a number after the object name. This is the "instance subidentifier" of that particular MIB instance. For values in tables (such as the sysORTable), this acts as an index into the table - a very familiar concept. But *all* SNMP values will display an instance number, whether or not they are part of a table. For non-table objects ("scalars"), this instance subidentifier will always be '0', and it *must* be included when making a GET request. Compare the following: $ snmpget -v1 -c public localhost sysUpTime Error in packet Reason: (noSuchName) There is no such variable name in this MIB. This name doesn't exist: system.sysUpTime $ snmpget -v1 -c public localhost sysUpTime.0 system.sysUpTime.0 = Timeticks: (69189271) 8 days, 0:11:32.71 This is a little less obscure when using SNMPv2c or v3 requests: $ snmpget -v 2c -c public localhost sysUpTime system.sysUpTime = No Such Instance currently exists Why do I sometimes get "End of MIB" when walking a tree, and sometimes not? -------------------------------------------------------------------------- This depends on which MIB modules are supported by the agent you are querying and exactly what you're asking for. Note that a tree is walked by repeatedly asking for "the next entry" until all the values under that tree have been retrieved. However, the agent has no idea that this is what's happening - all it sees is a request for "the next entry after X". If the object X happens to be the last entry in a sub-tree, the agent will provide the next object supported (as requested) even though this will be in a different subtree. It's up to the querying tool to recognise that this last result lies outside the area of interest, and simply discard it. If the object X happens to be the last entry supported by the agent, it doesn't have another object to provide, so returns an "end of MIB" indication. The Net-SNMP tools report this with the message above. But in either case, the actual information provided will be the same. How do I use SNMPv3? ------------------- The simplest form of SNMPv3 request is unauthenticated and unencrypted (noAuthNoPriv). It simply requires a user name, and would look something like: snmpget -v 3 -l noAuthNoPriv -u dave localhost sysUpTime.0 However this approach foregoes the security protection which is the main advantage of using SNMPv3 (and the agent must also be explicitly configured to allow unauthenticated requests from that user). The most common form of SNMPv3 request is authenticated but not encrypted (authNoPriv). This specifies the pass phrase to authenticate with: snmpget -v 3 -l authNoPriv -u dave -A "Open the Door" localhost sysUpTime.0 A fully secure (i.e. encrypted) request (authPriv) would also specify the privacy pass phrase: snmpget -v 3 -l authPriv -u dave -A "Open the Door" -X "Bet you can't see me" localhost sysUpTime.0 In practise, most of these would probably be set via configuration directives in a personal $HOME/.snmp/snmp.conf file (note, *not* the agent's snmpd.conf file). The equivalent settings for the third example would be: defSecurityName dave defSecurityLevel authPriv defAuthPassphrase "Open the Door" defPrivPassphrase "Bet you can't see me" If the AuthPassphrase and the PrivPassphrase are the same, then you can use the single setting defPassphrase "Open the Door and see me" instead. See the AGENT section for how to configure the agent for SNMPv3 access. Why can't I set any variables in the MIB? ---------------------------------------- There are three possible reasons for this: Many MIB objects are defined as "read-only" and inherently cannot be changed via SET requests. Attempts to do so will typically be rejected by the 'snmpset' command without ever being sent to the agent. Of those objects that can in principle be changed, the agent may not include the code necessary to support SET requests. (GET and GETNEXT are much easier to handle - particularly for objects relating to the internals of the underlying operating system). Even if SET support has been implemented, the agent may not be configured to allow write access to this object. Ready-installed distributions (such as those shipped with Linux) tend to be configured with read-only access to part of the mib tree (typically just the system group) and no write access at all. To change this, you will need to set up the agent's access control configuration. See the AGENT section for more details. Note that neither the community string "public" nor "private" can be used to set variables in a typical default configuration. Variables seem to disappear when I try to set them. Why? -------------------------------------------------------- This is actually the same as the previous question - it just isn't particularly obvious, particularly when using SNMPv1. A typical example of this effect would be $ snmpget -v1 -c public localhost sysLocation.0 sysLocation.0 = somewhere nearby $ snmpset -v1 -c public localhost sysLocation.0 s "right here" Error in packet. Reason: (noSuchName) There is no such variable name in this MIB. This name doesn't exist: sysLocation.0 Trying the same request using SNMPv2 or above is somewhat more informative: $ snmpset -v 2c -c public localhost sysLocation.0 s "right here" Error in packet. Reason: notWritable The SNMPv1 error 'noSuchName' actually means: "You can't do that to this variable" rather than "this variable doesn't exist". It may be the case that it doesn't exist at all. It may exist but you don't have access to it (although different administrative credentials might be accepted). Or it may exist, but you simply can't perform that particular operation (e.g. changing it). Similarly, the SNMPv2 error 'notWritable' means "not writable in this particular case" rather than "not writable under any circumstances". If you are sure that the object is both defined as writable, and has been implemented as such, then you probably need to look at the agent access control. See the AGENT section for more details. But see the next entry first. Why can't I change sysLocation (or sysContact)? ---------------------------------------------- There is one final possibility to consider for why a SET request might be rejected. The values for certain MIB objects (including 'sysLocation' and 'sysContact') can be configured via the snmpd.conf file. If this is done, then these particular objects become read-only, and cannot be updated via SET commands, even if the access control settings would otherwise allow it. This may seem perverse, but there is good reason for it. If there is a configuration setting for one of these objects, then that value will be used whenever the agent re-starts. If the object was allowed to be updated using SET, this new value would be forgotten the next time the agent was re-started. Hence the Net-SNMP agent rejects such requests if there's a value configured via the 'snmpd.conf' file. If there isn't such a config setting, then the write request will succeed (assuming suitable access control settings), and the new value will be retained the next time the agent restarts. I get an error when trying to set a negative value - why? -------------------------------------------------------- This is a different problem. What's happening here is that the routine that parses the arguments to the 'snmpset' command is seeing the '-' of the new value, and treating it as a command-line option. This normally generates an error (since digits typically aren't valid command line options). The easiest way to solve this is include the "end-of-option" indicator '--' in the command line, somewhere before the new value (but after all of the options, obviously). For example: snmpset -v 2c -c public localhost -- versionRestartAgent.0 i -1 (This command will still fail, since -1 isn't an acceptable value for this particular object, but that's not the point here!) I get an error when trying to query a string-indexed table value - why? ---------------------------------------------------------------------- The Net-SNMP library will normally try to interpret string-based index values, and display them in a meaningful manner: $ snmpgetnext .... vacmGroupName vacmGroupName.3."dave" = theWorkers The command-line tools will also accept string-valued indexes within an OID, and convert them into the appropriate numeric form before sending an SNMP request. However the Unix shell will typically swallow the quotes around the string index value, before the SNMP tools can get a chance to interpret them. The answer is to escape the quotes, to protect them from the shell, and allow them to be passed through to the OID parser: snmpget .... vacmGroupName.3.\"dave\" or snmpget .... 'vacmGroupName.3."dave"' Another alternative is to avoid trying to specify the index value as a string, and provide the numeric subidentifiers directly: snmpget .... vacmGroupName.3.4.100.97.118.101 (where '3' indicates SNMPv3, '4' is the length of the string index, followed by the ASCII values of the individual characters). The command-line option '-Ob' will display the results of querying a string-indexed table in this format: $ snmpgetnext -Ob .... vacmGroupName vacmGroupName.3.4.100.97.118.101 = theWorkers How should I specify string-indexed table values? ------------------------------------------------ There's one other aspect of string-indexed tables that can cause problems - the difference between implicit- and explicit-length strings, and how to represent these when making an SNMP query. The most common style of string index uses an explicit length, followed by the individual ASCII character values: "dave" = 4.'d'.'a'.'v'.'e' (as shown in the previous entry). However if the string index is defined in the MIB file as IMPLIED (or if it has a fixed length, such as a physical ethernet address), then the length subidentifier is omitted, and the index simply consists of the character values: "dave" = 'd'.'a'.'v'.'e' Note that IMPLIED index objects can only appear as the *last* index for a table. The Net-SNMP library uses double quotes (i.e. "dave) to indicate an explicit length string index value, and single quotes (i.e. 'dave') to indicate an implicit length one. If you use the wrong style of quotes, then the resulting OID will be incorrect, and you'll get confusing results to your query. How do I send traps and notifications? --------------------------------------- Traps and notifications can be sent using the command 'snmptrap'. The following examples generate the generic trap 'warmStart(1)' and a (dummy) enterprise specific trap '99' respectively: snmptrap -v 1 -c public localhost "" "" 1 0 "" snmptrap -v 1 -c public localhost "" "" 6 99 "" The empty parameters "" will use suitable defaults for the relevant values (enterprise OID, address of sender and current sysUptime). An SNMPv2 or SNMPv3 notification (either trap or inform) takes the OID of the trap to send: snmptrap -v 2c -c public localhost "" UCD-SNMP-MIB::ucdStart snmptrap -v 2c -c public localhost "" .1.3.6.1.4.1.2021.251.1 (These two are equivalent ways of specifying the same trap). Again, the empty parameter "" will use a suitable default for the relevant value (sysUptime). Any of these commands can be followed by one or more varbinds, using the same (OID/type/value) syntax as for 'snmpset': snmptrap -v 2c -c public localhost "" ucdStart sysContact.0 s "Dave" Generating traps from within the agent, or other applications, is covered in the AGENT and CODING sections. You should also read the snmptrap tutorial at http://www.net-snmp.org/wiki/index.php/TUT:snmptrap which will help you understand everything you need to know about traps. How do I receive traps and notifications? ---------------------------------------- Handling incoming traps is the job of a "notification receiver". The Net-SNMP suite include the tool 'snmptrapd' to act in this role. This can log traps to a file or via the syslog mechanism, forward them to another notification receiver and/or invoke a specified command whenever a particular notification is received. Logging notifications would be done by starting snmptrapd as: snmptrapd -Ls 7 (log to syslog using 'LOCAL7') or snmptrapd -f -Lo (log to standard output) Invoking a command to process a received notification uses one or more 'traphandle' directives in the configuration file 'snmptrapd.conf'. A typical configuration might look something like: traphandle .1.3.6.1.6.3.1.5.1 /path/to/page_me up traphandle .1.3.6.1.4.1.2021.251.1 /path/to/page_me up traphandle .1.3.6.1.4.1.2021.251.2 /path/to/page_me down traphandle default /path/to/log_it where 'page_me' and 'log_it' are the commands to be run. Forwarding notifications to another receiver would be done using similar 'snmptrapd.conf' directives: forward .1.3.6.1.4.1.8072.4.0.3 10.0.0.1 forward default 10.0.0.2 There's a tutorial with more details on the web site at http://www.net-snmp.org/wiki/index.php/TUT:snmptrap How do I receive SNMPv1 traps? ----------------------------- Directives in the 'snmptrapd.conf' file use the (SNMPv2) snmpTrapOID value to identify individual notifications. This applies to *all* versions of SNMP - including SNMPv1 traps. See the co-existence spec (RFC 2576) for details of mapping SNMPv1 traps to SNMPv2 OIDs. Note that the first traphandle directive in the previous entry uses the OID corresponding to the SNMPv1 'coldStart' trap. Why don't I receive incoming traps? ---------------------------------- Starting with net-snmp 5.3, snmptrapd will no longer automatically accept all incoming traps. It must be configured with authorized SNMPv1/v2c community strings and/or SNMPv3 users. Non-authorized traps/informs will be dropped. Please refer to the snmptrapd.conf(5) manual page for details. My traphandler script doesn't work when run like this - why not? --------------------------------------------------------------- If a traphandler script works fine when run manually from the command line, but fails or generates an error when triggered by an incoming notification, then there are two likely causes. Firstly, the interactive shell environment may not be precisely the same as that for programs executed by the snmptrapd daemon. In particular, it's quite possible that the PATH environmental variable may not include all the additional directories that are commonly set up for a personal login configuration. To avoid this problem (particularly for traphandler shell scripts), it's worth giving the full path to all programs used within the script. Secondly, the snmptrapd daemon may not always recognise the appropriate interpreter to use for a particular trap handler. If this is the case, then you can specify this interpreter explicitly as part of the trap handle directive: traphandle default /usr/bin/perl /usr/local/bin/log_it In this case, it's almost certain that you'll also need to give the full path to the traphandle script (as shown) How can the agent receive traps and notifications? ------------------------------------------------- It can't. The primary purpose of an SNMP agent is to handle requests for information from management applications. In SNMP terminology, it acts as a "command responder". It may also issue traps to report significant events or conditions ("notification generator"). But responding to such notifications is a significantly different role, and this is handled by a separate application ('snmptrapd'). Note that it is perfectly possible (even normal) for both agent and trap receiver to run on the same host. How big can an SNMP request (or reply) be? ----------------------------------------- The protocol definition specifies a "minimum maximum" packet size (484 bytes for UDP), which all systems must support, but does not attempt to define an upper bound for this maximum size. This is left to each individual implementation. The UCD software used a fixed size buffer of 1472 bytes to hold the encoded packet, so all requests and responses had to fit within this. The Net-SNMP releases handle packet buffers rather differently, and are not subject to the same fixed restrictions. How can I monitor my systems (disk, memory, etc)? ------------------------------------------------ In general, the Net-SNMP suite consists of relatively low-level tools, and there is nothing included that is designed for high-level, long-term monitoring of trends in network traffic, disk or memory usage, etc. There are a number of packages available that are designed for this purpose. Two of the most widely used are MRTG (http://www.mrtg.org/) and RRDtool (http://oss.oetiker.ch/rrdtool/). There are also several frontends built on top of RRDtool, including Cacti (http://www.cacti.net/) and Cricket (http://cricket.sourceforge.net/). There are details of how to set up Cricket to monitor some of the UCD extensions at http://www.afn.org/~jam/software/cricket/ We have also set up a page that describes in detail how MRTG can be set up to monitor disk, memory and cpu activity at http://www.net-snmp.org/tutorial-5/mrtg/index.html There is also a web-based network configuration system "Net-Policy", based upon SNMP. This is not strictly connected to the Net-SNMP project, but a number of the core developers are also involved with that system. See http://net-policy.sourceforge.net for more details. Applications complain about entries in your example 'snmp.conf' file. Why? -------------------------------------------------------------------------- There *is* no example 'snmp.conf' shipped with the standard distribution. The configuration file 'EXAMPLE.conf' is designed as a config for the agent, and should be installed as 'snmpd.conf' (note the 'd'). The file 'snmp.conf' is intended for general configuration options, applicable to all applications (via the SNMP library). Rename (or merge) the 'snmp.conf' file to 'snmpd.conf', and this should fix the problem. See the AGENT section or the 'snmpd.conf(5)' man page for more information about what should go in this file. OK, what should I put in snmp.conf? ---------------------------------- This is used to set common configuration values for most of the applications, to avoid having to specify them every time. Examples are the SNMPv3 settings mentioned above, defaults for which MIBs to load and where from (see the second entry in this section), and the default SNMP version, port and (if appropriate) community string to use. Some of these (such as MIB information), might be best put in a shared snmp.conf file (typically /usr/local/share/snmp/snmp.conf or /etc/snmp/snmp.conf) to apply to all users of the system. Others (particularly the SNMPv3 security settings), are more likely to refer to a particular user, and should probably go in a personal snmp.conf file (typically $HOME/.snmp/snmp.conf). See 'snmpget -H' and/or the snmp.conf(5) man page for more details. You can also use the "snmpconf" command to help you generate your snmp.conf configuration file (just run it and answer its questions). How do I specify IPv6 addresses in tools command line arguments? --------------------------------------------------------------- IPv6 addresses pose a particular problem for the Net-SNMP command line tools, which parse host names into pieces. In particular, normally if you specify a simple host name, it assumes you want UDP in IPv4 on port 161. By default, these two commands are actually the same: snmpget 127.0.0.1 sysUpTime.0 snmpget udp:127.0.0.1:161 sysUpTime.0 However, for IPv6 this causes a problem because IPv6 addresses also use a colon to separate addressing parts. Thus you need to enclose the address in square brackets ( [ and ] ). Because most shells use these brackets too, you also likely need to quote it: snmpget 'udp6:[::1]:161' sysUpTime.0 PERL ==== What is the purpose of the Perl SNMP module? ------------------------------------------- Short, comprehensive (but ultimately unhelpful) anwer - to provide a perl interface for SNMP operations. Longer, incomplete (but more useful) answer - there are probably two main uses for the Perl SNMP module. The first is for developing client management applications, using perl to send SNMP requests, and manipulating or displaying the results. As such, this is a straight alternative to various other SNMP toolkits currently available (for both perl and other programming languages). The second is as a means for extending the functionality of the Net-SNMP agent, by implementing new MIB modules. This is an alternative to the other script-based extension mechanisms, but is more tightly bound to the Net-SNMP agent (and hence more efficient), while still avoiding the need to write C code. It is also possible to use the perl SNMP module in the snmpd.conf file, or to process incoming notifications, but the above are probably the two primary uses. Where can I get the Perl SNMP package? ------------------------------------- Joe Marzot's excellent Perl 'SNMP' module, is included in the Net-SNMP source releases. It can be found located in the perl/SNMP subdirectory of the source tree. This is accompanied by a number of Perl modules grouped together under the NetSNMP namespace. The basic SNMP module (though not the NetSNMP additions), can also be found at any Comprehensive Perl Archive Network (CPAN) mirror site, under modules/by-module/SNMP. To find the CPAN site nearest you, please see http://www.cpan.org/SITES.html. These Perl modules need to be used in conjunction with a compatible version of the Net-SNMP library. Consult the README file in the SNMP Perl distribution to find out which version of the library it needs. How do I install the Perl SNMP modules? -------------------------------------- Assuming you have a reasonably new (and properly configured) Perl system, this should be simply: cd perl perl Makefile.PL (press RETURN when prompted for host and community) make make test make install (probably as root) It might be possible to install the basic module using perl -MCPAN -e shell ; "install SNMP" but this has not been reliably tested, and very much relies on having the correct version of the Net-SNMP library. There may also be appropriate pre-compiled versions of the Perl modules available from the Net-SNMP project website, or your O/S vendor. But compiling this fails! Why? ----------------------------- The Perl module tends to delve quite deeply into the internals of the main Net-SNMP library, and so is quite sensitive to changes within the library. It's important to use the correct version of the module, that corresponds to the version of the library you have installed. If you're working with a Net-SNMP source distribution, the appropriate versions of the Perl modules are shipped as part of the source code, but you *must* have run "make install" on the main Net-SNMP distribution *first*. If you're working with a ready-installed version of the library, make sure you obtain a compatible version of the Perl module. Note that the Perl modules will be compiled using the compiler (and compiler settings) used for compiling the original perl binary, *not* those used for compiling the Net-SNMP (or UCD) library. If these are different (e.g. 'gcc' used for one and 'cc' for the other) then this may well cause problems. It's much safer to use a consistent environment for both. This issue is discussed in greater detail in the README.solaris file. Also note that the v5 Net-SNMP suite *must* be configured to provide shared libraries in order for the Perl modules to work correctly. This is not necessary with the v4 UCD-SNMP libraries. Compiling the Perl module works OK, but 'make test' fails. Why? -------------------------------------------------------------- That's difficult to answer in general. Some of the Perl tests are rather picky, so this may simply be some minor inconsistency between your precise setup, and the expectations of the test environment. Check that you are working with the Perl distribution that matches the SNMP libraries (use the 'perl/SNMP' in preference to CPAN), and that you have installed the main libraries successfully (uninstall any old versions if you're having trouble). If all this looks OK, and if most of the tests pass, then it's probably safe to run 'make install' anyway. Probably. Why can't mib2c (or tkmib) locate SNMP.pm? ----------------------------------------- That's probably because the SNMP Perl module hasn't been installed. It's not part of the standard Perl distribution, nor is it included in the default Fedora Linux installation (for example). You'll need to install it yourself. See the second entry in this section. Why can't mib2c (or tkmib) load SNMP.so? --------------------------------------- This is probably the same problem. Either the SNMP module hasn't been installed, or it's the wrong version. See the previous questions. Why can't tkmib locate Tk.pm? ---------------------------- Tk.pm is another Perl package that needs to be installed before tkmib will run. It's also available on Perl CPAN. We suggest using version "Tk800.011" or later. It can be installed by issuing the command: perl -MCPAN -e shell ; "install Tk" Why does your RPM complain about missing Perl modules? ----------------------------------------------------- This has been particularly noted on RedHat 9, complaining about the module "perl(Term::ReadKey)" - even if this is actually present (e.g. having been installed directly from CPAN). In fact, this is not specific to Perl modules - the same issue can potentially arise with other RPM dependencies. The problem is that the RPM mechanism keeps a local database of what software packages have been installed, and checks this for any other features that this RPM requires. If software is installed "manually" rather than via rpm packages, then it will not appear in this database. Attempting to install another RPM that rely on this functionality will then complain about the "missing" package, because the RPM system doesn't know that's it's actually available. The ideal solution is to *always* install software using a consistent mechanism (which may involve building RPMs locally, or looking for a suitable pre-built version). Failing this, it's possible to tell the "rpm" command to ignore such dependencies, and install the package anyway. Try: rpm -i --nodeps {package} In this situation, it's then up to you to make sure that any other necessary packages *are* actually present on the system. I've got a problem with the Net-SNMP module. Can you help? ---------------------------------------------------------- Sorry, despite the similar-sounding name, the Net-SNMP (or Net::SNMP) module is nothing to do with this package, or the NetSNMP modules. Net::SNMP is a "pure-perl" implementation of SNMP support, developed by David Town. The developers of the (C-based) Net-SNMP suite do not have any significant experience in using this particular module, and you'll probably be better off asking for help via CPAN or some other perl-related forum. MIBS ==== Where can I find a MIB compiler? ------------------------------- That depends what you mean by a "MIB compiler". There are at least two types of tool that are commonly referred to by this name. The first is a tool to check MIB files for validity. With the Net-SNMP software, this functionality is mostly integrated within the MIB parser, and hence included in all the applications. The tool 'snmptranslate' is probably the most appropriate for this purpose. Note that the parser is fairly forgiving (see 'What ASN.1 parser is used' below), so this should not be regarded as a stamp of approval. For a more rigourous validation, use a tool such as 'smilint', or the on-line interface at http://wwwsnmp.cs.utwente.nl/ietf/mibs/validate/ The second type of "MIB compiler" is one to turn a MIB specification into C code, specifically one designed to aid agent implementation. The command 'mib2c' is an example of such a tool for the Net-SNMP agent. See the CODING section for more information. Why aren't my MIB files being read in? ------------------------------------- There are two basic likely causes - either the library isn't attemping to load these particular MIB files, or it's trying to load them but can't locate them. By default, the Net-SNMP library loads a specific subset of MIB files. This list is set when the suite is first configured and compiled, and basically corresponds to the list of modules that the agent supports. (This is a simplification, but is a reasonable first approximation). In order to load additional MIB files, it is necessary to add them to this default list. See the FAQ entry "How do I add a MIB to the tools?" for more information about how to do this. Alternatively, the tools may be looking in the wrong place. The directory where the library looks for MIB files is also set when the software is first configured and compiled. If you put new MIB files in the wrong location, then the library won't be able to find them (and will complain). This problem may arise when switching from a vendor-supplied distribution to one compiled from source (or vice versa). See the next entry for more information. Where should I put my MIB files? ------------------------------- If you've compiled the package from source (or are using binaries from the project website), then you should probably put new MIB files in the directory /usr/local/share/snmp/mibs If you are using vendor-supplied binaries, then the MIB files may well be located somewhere else (e.g. /usr/share/snmp/mibs, /opt/snmp/mibs, or /etc/sma/snmp/mibs). Have a look for where existing MIB files are installed, and try adding your MIBs to the same directory. If you compiled the source yourself, but specified a different --prefix value when running configure, then the location of the MIB directory will be {prefix}/share/snmp/mibs. If you're still not sure where to put your MIB files, try running the command snmpget -Dparse-mibs 2>&1 | grep directory This will display the location(s) where the library is looking for MIB files. What does "Cannot find module (XXX-MIB)" mean? --------------------------------------------- If this error is only generated for one or two modules, then it's likely that the named modules are not being found - perhaps they're not installed in the correct location, are not readable, or the name being used is incorrect. See the previous entries and the entry "How do I add a MIB to the tools?" for more details. Note that the name reported is the name of the MIB *module*, which is not necessarily the same as the name of the file. If there are a large number of such errors, then it's more likely that either the MIB files haven't been installed at all. If you are compiling from source, then it is necessary to run "make install" in order to set up the full run-time environment. Otherwise, see the previous entry to check whether the MIBs are installed in the correct location for the tools to find them. I'm getting answers, but they're all numbers. Why? ------------------------------------------------- This is related to the previous questions. Remember, the results that you receive from an agent do not depend on which MIBs are loaded by the client tools - purely on how the agent was compiled and configured. Because the tools don't necessarily read in every MIB file they can find (and the relevant MIB file may not be available anyway), it is quite possible for results from an agent to refer to modules that have not been loaded (particularly with GETNEXT requests, or when walking a tree). The results will be reported correctly, but won't be translated to use named identifiers (or display the values in the most appropriate manner). To fix this, add the missing MIB files to the list of MIBs to be loaded. See the previous entries and the entry "How do I add a MIB to the tools?" for more information. What does "unlinked OID" mean? ----------------------------- This means that the library has been able to find the MIB module, and parse the individual objects defined in it, but is having problems linking them together into a consistent tree. In particular, it can't find an object corresponding to the name within the braces (i.e. the 'xxx' in '{xxx 99}'). This is probably due either to a typo in this name (remember that names are case sensitive, so a reference to 'xxx' will *not* match a definition of 'Xxx'), or else the name is defined in another MIB file, and this dependency is missing from the IMPORT clause of this MIB file. The parser doesn't handle comments properly. Why not? ---------------------------------------------------- The way that comments are handled in a MIB file is subtly different to the equivalent syntax in most typical programming languages, and this difference can catch out the unwary. In particular, there are two common situations which can lead to problems. The first scenario is where the MIB designer has attempted to "comment out" an unwanted line that already contains a comment: -- broken ::= { myMIB 1 } -- This isn't working yet The assumption here is that a comment continues to the end of the line. Unfortunately, this is not correct. A comment will continue either to the end of the line, *or* the next occurance of a pair of dashes. Thus in this case, the definition of "broken" is commented out (as intended) but the following text ("This isn't working yet") is treated as an active part of the MIB, and will generate an error. The second scenario is where a line of dashes has been used to mark out separate parts of a MIB file. Depending on the exact number of dashes used, this may still result in a syntactically valid MIB file, but has a 1-in-4 possibility of triggering an error. This means that this particular situation can be particularly difficult to spot! Most of the Net-SNMP applications have a command-line option (-Pc) which will work around this problem by treating the whole line as a comment. But this is not strictly legal, and the offending MIB file should really be corrected. How can I get more information about problems with MIB files? ------------------------------------------------------------ The command 'snmptranslate' is used to translate between numeric and symbolic forms of OIDs. It uses the same MIB parsing routines as the commands that actually communicate with a network management agent, but can be used standalone. As such, it is a useful tool for identifying problems with reading in MIB files. In particular, the following options may be useful in identifying problems: -Pw warns about conflicting symbols -PW prints more verbose warnings about other problems as well (in both cases, ignore the 'xmalloc' reports) -T provides sub-options for various views of these entries There are other '-P' options to control various aspects of MIB parsing. See the 'snmptranslate(1)' and 'snmpcmd(1)' man pages for more details, or the tutorial at http://www.net-snmp.org/tutorial-5/commands/snmptranslate.html For a more rigourous validation, use a tool such as 'smilint', or the on-line interface at http://wwwsnmp.cs.utwente.nl/ietf/mibs/validate/ What's this about "too many imported symbols"? --------------------------------------------- Any MIB file starts with an (optional) list of identifiers that it "imports" from other files. The parser handles this using a fixed size buffer to hold the import information. There are two circumstances in which this can result in the error message shown above. Firstly, if the MIB file refers to an unusually large number of external identifiers. Handling this case requires a (trivial) patch to the parsing code. Contact the coders list for advice. (This is extremely rare - the only example that we've come across is the Cabletron Trap MIB). Much more common is a syntax error in the IMPORTS clause of the MIB file in question. In particular, check that this section ends in a semicolon, before going on to the main MIB object definitions. Do I actually need the MIB files? -------------------------------- Probably not. The MIB files play two main roles - they are used to translate between numeric OIDs and the corresponding textual names, and they define the structure and syntax of the relevant MIB objects. This second role is perhaps best thought of in terms of a design document. It's vital while developing an application (typically the MIB module or handler within the agent), since it defines what the application (MIB) must actually do. But once the code has been written, the design document becomes redundent. The agent then has the same information hardcoded into it (literally!), and no longer needs the MIB file. The translation task is not strictly necessary - SNMP will operate fine without any MIB files at all, as long as you're happy to work with numeric OIDs throughout, and know which MIB objects you're interested in. But it's much easier to work with the (hopefully) meaningful names, enumeration tags and the like, and to view the description of a particular object. This requires having the relevant MIB files installed and loaded. Since the agent needs MIBs the least and some systems are memory restricted, it is possible to completely disable loading these MIBs as well as remove the code that does the parsing by using the --disable-mib-loading flag to configure. However, note that certain snmpd.conf tokens actually make use of mib information so they won't be as easily usable. AGENT ===== What MIBs are supported? ----------------------- The following MIBs are supported (at least in part and on some systems): - MIB-2 General network statistics (RFC 1213 and subsequent revisions) - Host Resources (RFC 1514 and 2790) - SNMPv3 framework (RFCs 2571-5, 3411-3418) (including USM, VACM, Target and Notification MIBs) - DisMan Event and Schedule MIBs - MTA-MIB (sendmail) - private UCD/Net-SNMP agent extensions (monitor specified processes and disks, memory, CPU, load average, + extending the agent using shell commands) See README.agent-mibs for details. Not all MIB modules are included by default on all systems. Some of these may need to be explicitly requested when the software is first configured and built, while others may not be available on all architectures. There are a few other MIB implementations distributed as part of the source tarball, but these are basically unsupported and most of the core developers have little or no experience with using them. What protocols are supported? ---------------------------- The agent supports all three current versions of SNMP (v1, v2c and v3), over both UDP and TCP transports, as well as acting as a SMUX (RFC 1227) master agent, AgentX (RFC 2741) in both master and subagent roles, and SNMP proxying. How do I configure the agent? ---------------------------- That's a somewhat ambiguous question, as there are two very different stages where it is possible to "configure" the agent. Firstly, you can determine what capabilities and defaults are included within the library and agent, at the time that the software is first built. This uses suitable flags to the 'configure' script, before compiling the source. As far as the agent is concerned, the most significant option is '--with-mib-modules' (or '--with-out-mib-modules') to control which MIBs will be supported by the agent. See the next few entries for details. You can also control various aspects of the agent behaviour (and the information it returns) at run time, via the 'snmpd.conf' configuration file. Various aspects of this are touched on throughout this FAQ. Or see the snmpd.conf(5) manual page for full details. The "snmpconf" script can help in creating this config file. Start off with 'snmpconf -g basic_setup' to get you going. How do I remove a MIB from the agent? ------------------------------------ Deleting the text file for a MIB does not affect the agent (other than to prevent it from recognising MIB object names in the config files). It's necessary to tell the agent not to activate the relevant code that actually implements these objects. There are three ways to do this: 1) re-run 'configure' to exclude the given MIB module(s) from the build configuration, then recompile and reinstall: ./configure --with-out-mib-modules=path/to/unwanted .... make make install This specifies the path to the module code file, relative to the 'agent/mibgroup' directory. Clearly, this approach is only possible if you are working with a source distribution. 2) disable the MIB at runtime snmpd -I -unwanted Note that this relies on knowing which modules are used to implement the relevant MIB objects. If you're not sure, you could try walking the 'nsModuleName' MIB object, which indicates the module responsible for each particular range of OIDs. You can also check which MIB modules are loaded by getting the agent to report them as they are initialised: snmpd -Dmib_init -H From this information, it should then be fairly obvious which modules to disable. 3) use access control to exclude the mib from the view used to query the agent: view almostEverything included .1 view almostEverything excluded unwantedMib rocommunity public default -V almostEverything This approach can also be used with the full com2sec/group/access configuration directives (e.g. with versions earlier than 5.3, which don't support the above mechanism). I've installed a new MIB file. Why can't I query it? ---------------------------------------------------- Installing a new MIB file will not magically enable the agent to know what values to report for the objects defined in that MIB. It's necessary to have some code which can provide the relevant information. The next few entries, and the CODING section address this issue in more detail. How do I add a MIB to the agent? ------------------------------- Adding a MIB essentially involves writing some code to implement the objects defined in the new MIB. There are three basic approaches that can be used to do this: - The agent can invoke an external command or shell script to return the necessary information. There are several possible variations on this approach - see the next entry for details. - The agent can pass the request off to another (sub-)agent, which already implements the required MIB. Again, there are several ways of doing this - including AgentX, SMUX and proxied SNMP. See the next entry but one for details. - You can write code to implement the new MIB objects, and include this within the agent. This is most commonly C (or C++) code, although the agent can also support MIB modules implemented in perl. See the next section (CODING) for more details. Note that there is no visible difference between external commands, subagents, and modules implemented within the main agent itself. Tools querying the agent will see a single MIB structure. What's the difference between 'exec', 'sh', 'extend' and 'pass'? --------------------------------------------------------------- 'exec' will run the specified command and return the exit status and output. Any arguments are passed directly to the command, with no special interpretation. 'sh' is similar, but invokes a shell to run the command line given. This means that quoted arguments will be recognised as such, and also allows redirection, and other similar shell interpretation. The results are returned in exactly the same way. 'extend' is also similar, but provides a richer and more flexible MIB framework - both for configuring the exact command to be run, and for displaying the results. None of these mechanisms require the command to have any knowledge of SNMP, or the fact that they are being used in this manner. But the output is returned in a fixed format, and it is up to the receiving application to interpret this appropriately. Note that the "relocatable" form of the 'exec' directive ('exec OID ....') produces MIB output that is not strictly valid. For this reason, support for this has been deprecated in favour of 'extend OID ...', which produces well-formed MIB results (as well as providing fuller functionality). The most recent releases of the agent don't include support for "relocatable exec" by default. This needs to be explicitly included when the agent is first compiled, by including the module 'ucd-snmp/extensible' instead of 'agent/extend'. 'pass' is a more general mechanism for implementing arbitrary MIB objects. The specified command will be invoked for any request within the named MIB subtree, and passed details of the requested OID. It should return the information relevant to the requested OID. 'pass-persist' is similar, but the command will continue running even after the initial request has been answered. These two mechanisms can be used to implement a particular MIB, following the correct MIB structure (as opposed to the fixed format of exec/sh/extend). All of these mechanisms are described in the 'snmpd.conf(5)' man page, in the section entitled "Extending Agent Functionality". What's the difference between AgentX, SMUX and proxied SNMP? ----------------------------------------------------------- All three are protocols that can be used to make two or more agents appear as one to the querying application. In each case, one agent takes the role of "master", and delegates requests to one of the others as and where this is appropriate. The differences between them mainly relate to how data is represented, and the mechanisms for communication between master and subagents. SMUX and proxy SNMP both essentially use the standard SNMP packet format. The main difference is that a proxy SNMP subagent need not be aware that it is acting in such a role. It typically listens on a non-standard port, and simply receives requests as usual, forwarded from the master agent (rather than directly). The main issue to be aware of is that such requests will appear to come from the local host, and this may affect how the access control mechanisms need to be set up. SMUX uses a similar packet format, but the subagent "registers" with the master agent, providing a suitable password. The Net-SNMP (and UCD) agent includes the possibility of acting as a SMUX master agent, but the suite does not include a subagent API. Note that support for SMUX is not included by default, and needs to be explicitly enabled by running: --with-mib-modules=smux before re-compiling the agent. See the file 'agent/mibgroup/README.smux' for details. AgentX uses a more compact (and simpler) packet format, with a richer range of administrative commands, and provides a more flexible and reliable extension mechanism. The Net-SNMP agent can be used in both master and subagent roles, and the agent library can also be used to embed an AgentX subagent within another application. See the file 'README.agentx' for details. AgentX support is included by default, but needs to be explicitly activated in the master agent. Do this by adding the line master agentx to the snmpd.conf file before starting the agent. What is the purpose of 'dlmod'? ------------------------------ Most of the MIB information supplied by the Net-SNMP agent is provided by C-coded implementation modules, and the choice of which modules to include is usually made when the agent is first built. Adding new MIB modules would therefore require re-compiling the agent. This is not always convenient - particularly when working with a production system, and/or pre-installed binaries. Dynamically loaded modules are a means of including a MIB implementation module within the main SNMP agent (or an AgentX subagent) without needing to re-compile and re-link the agent binary. Instead, details of the module(s) to load are specified in the configuration file, and the agent locates the files listed, and merges them in at run time. See http://www.net-snmp.org/tutorial-5/toolkit/dlmod/ for more information. Which extension mechanism should I use? -------------------------------------- That's not easy to answer in general. If there's an existing agent that already implements the desired new MIB, then it makes sense to re-use that, via whatever extension protocol that agent might support. Note that the SMUX protocol has essentially been superceded by AgentX, which provides a fuller and more reliable mechanism than either SMUX or proxied SNMP. So ideally, this would be the preferred extension approach. But if the target subagent only supports SMUX or basic SNMP, then that would dictate the extension protocol to use. Implementing the module in C within the main agent (directly or via dlmod) is probably the most efficient and reliable, closely followed by embedded perl (or python) extensions. These have the advantage of minimal overheads between the code implementing the MIB module, and the agent framework, and no inter-process communication issues. But this does assume that there's a suitable mechanism for retrieving the necessary information. If the new MIB is monitoring or managing some other subsystem, external to the agent, then it may be necessary to embed a subagent within the subsystem itself - particularly if there's no suitable public API to retrieve the necessary information. In this case, AgentX is probably the most appropriate way forward. Alternatively, you could implement the missing public management API for that subsystem, and develop a module within the main agent instead. Can I use AgentX when running under Windows? ------------------------------------------- Yes, but there are a couple of things to be aware of. Firstly, by default the AgentX master listens on the Unix domain socket '/var/agentx/master', which doesn't work under Windows. You'll need to tell it to listen on a TCP port, either by using the command-line option "-x localhost:705", or by adding the directive "agentxSocket localhost:705" to the snmpd.conf file. Secondly, be aware that the security of AgentX connectivity is not particularly strong. The examples given here would allow any process running on the local machine to register as an AgentX subagent. The more obvious settings "-x 705" or "agentxSocket 705" would allow a system *anywhere* on the network (or even from remote networks) to register as an AgentX subagent. This could potentially be used to hijack the agent, or provide false information. How can I run AgentX with a different socket address? ---------------------------------------------------- There are two sides to an AgentX connection, and they need to agree about which socket address to use. So if you want to use a different socket, you need to configure both parties accordingly. The socket that the Net-SNMP master agent uses to listen for AgentX registrations (and send appropriate requests) can be specified using the option '-x'. The command "snmpd -x tcp:localhost:705 ...." would start the agent listening on the TCP port 705 for connections from the local system. The same effect can also be obtained by adding the line agentxsocket localhost:705 to the file 'snmpd.conf'. The same option can be used with the Net-SNMP agent when running in This also holds when the Net-SNMP agent is running in "subagent" mode, to specify the socket to register with (and receive requests from). So a subagent might connect to the master agent above (both running on the same host), using: "snmpd -X -x tcp:localhost:705 ...." A subagent running embedded within some other application will typically not understand the same command-line options, so would need to set the same configuration programmatically: netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_X_SOCKET, "tcp:localhost:705"); With the example subagent code from the Net-SNMP tutorial, this line would be added immediately before the 'init_agent' call. The same approach can also be used to listen on a different named socket, using: agentxsocket /tmp/agentx agentxperms 770 770 myuser mygroup or snmpd -x /tmp/agentx .... or netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_X_SOCKET, "/tmp/agentx"); as appropriate. How can I turn off SMUX support? ------------------------------- Normally, you would use the command-line option '-I -{module}' to disable the initialisation of a particular MIB module within the agent. Unfortunately, it's not currently possible to turn off SMUX support this way. The safest approach is to run configure --with-out-mib-modules=smux and recompile the agent. If this is not possible, an alternative workaround might be to have the agent bind the SMUX socket to an invalid IP address, using a snmpd.conf line such as: smuxsocket 1.0.0.0 The agent may complain at startup, but it won't accept any incoming SMUX requests. If the agent complains about not recognising the "smuxsocket" token, then you're out of luck. You'll either have to recompile from source, or use local firewall rules to block connections to port 199. How can I combine two copies of the 'mib2' tree from separate subagents? ----------------------------------------------------------------------- This is the purpose of the SNMPv3 'context' field. Register the MIB module a second time in a non-default context (see the relevant entry in the CODING section for details), and specify this context when querying the agent. The MIB module can use this context information to determine which set of information to report. Or you could register two completely different handlers for the same OID (using different contexts), and the agent will invoke the appropriate code. This holds for both MIB modules implemented within the main agent, or AgentX subagents - the same approach will work for both. Contexts can also be used with proxied SNMP requests - just specify the option '-Cn {context}' as part of the "proxy" entry. See the 'snmpd.conf(5)' man page for details. It's currently not possible to support parallel MIB trees when using SNMPv1 or SNMPv2c. In principle, it should be possible to use the community string in a similar way, but this has not (yet) been implemented. This mechanism is only available with the v5 Net-SNMP agent. The v4 UCD agent does not support contexts at all. Sorry about that. Another way to handle this would be to tweak one of the subagents to use a different set of (non-standard) OID assignments - perhaps by relocating the whole of the subtree to another (private) OID. This is not ideal, but should work with all configurations. What traps are sent by the agent? -------------------------------- The Net-SNMP agent sends a 'coldStart(0)' trap when it first starts up, and an enterprise-specific trap 'nsNotifyShutdown' when it stops. It generates an enterprise-specific trap 'nsNotifyRestart' (rather than the standard 'coldStart(0)' or 'warmStart(1)' traps) on receiving a HUP signal - typically after being re-configured. It can also be configured to send an 'authenticationFailure(4)' trap when it receives an SNMPv1 (or SNMPv2c) request using an unknown community name. The agent does not send 'linkUp' or 'linkDown' traps by default. It can be configured to do this using the directive 'linkUpDownNotifications'. See the 'snmpd.conf(5)' man page (under ACTIVE MONITORING) for details. Similarly, it does not generate traps by default when one of the monitored characteristics (disk usage, running processes, etc) enters or leaves an error state. This can be configured using the 'defaultMonitors' directive (again documented under ACTIVE MONITORING). Where are these traps sent to? ----------------------------- With all these alerts, the agent needs to be told where to send them, specifying the type of notification (v1 or v2 trap, or v2 inform) and the community name to use. This uses the snmpd.conf directives 'trapsink', 'trap2sink' and 'informsink' for the destination type, and 'trapcommunity' for the community name. SNMPv3 destinations can be configured using the directive 'trapsess'. See the 'snmpd.conf(5)' man page for details. Note that the type of trap generated is totally determined by these directives - irrespective of which API call was used to trigger sending the trap. See the trap-related entries in the CODING section for details. Note also that you typically only want *one* of the settings: trapsink localhost trap2sink localhost informsink localhost Including two (or all three) of these lines in the snmpd.conf file will will result in multiple copies of every notifications being sent for each call to 'send_easy_trap()' (or 'send_v2trap()'). This is probably not what was intended! How can I send a particular trap to selected destinations? ---------------------------------------------------------- This is not currently possible. All notifications will be sent to all configured destinations. The agent does not (currently) support notification filtering. There is a preliminary implementation of the snmpNotifyFilterTable which is designed to allow this sort of selective trap direction. However this is not currently active. (The tables are present and can be manipulated and updated, but the information is not consulted) Documentation on how to use this mechanism will appear once the functionality is working properly. When I run the agent it runs and then quits without staying around. Why? ----------------------------------------------------------------------- Firstly, are you certain that this is what is happening? The normal operation of the agent is to 'fork' itself into the background, detaching itself from the controlling terminal so that it will continue running even when you log out, and freeing the command line for subsequent use. This looks at first sight as if the agent has died, but using 'ps' to show all processes should reveal that the agent is still running. To prevent this behaviour (such as when attempting to debug the agent), you can start it with the '-f' flag. This suppresses the fork, and the agent will run as a 'normal' command. It's also often useful to use the '-Le' (or '-L') flag, to log messages to stderr. On the other hand, if 'ps' shows that the agent is not running, then this is an error, and probably show that something went wrong in starting the agent up. Check the agent log file for any error messages, or run it with '-f -Le' and see what it reports. One possible cause might be an existing agent (or some other process) that's already listening on the SNMP port. Trying to start a second agent will fail with an error about "opening the specified endpoint". If you're starting the agent as a non-root user, then this may also fail with the very same error. By default, the agent (and trap handler) will attempt to listen on the standard SNMP port 161 (or 162 for the trap handler). These are defined as "privileged ports", and processes will need to be running as root in order to open them. One way to tackle this is to start the agent as root, but use the -u option to switch to run as another user once the port has been opened. Alternatively, you can specify a different port to use instead. Anything greater than 1024 is available to non-root users. In this case, you'll also need to specify the same port when issuing client commands. After a while the agent stops responding, and starts eating CPU time. Why? -------------------------------------------------------------------------- This is basically the same problem described in the APPLICATIONS section, in the entry The agent worked for a while, then stopped responding. Why? See that entry for details. How can I stop other people getting at my agent? ----------------------------------------------- Firstly, are you concerned with read access or write access? As far as changing things on the agent is concerned, there is relatively little that can actually be altered (see the entry "Why can't I set any variables in the MIB?" above). If you are using the example config file, this is set up to allow read access from your local network, and write access only from the system itself (accessed as 'localhost'), both using the community name specified. You will need to set appropriate values for both NETWORK and COMMUNITY in this file before using it. This mechanism can also be used to control access much more precisely. (see the next few questions for details) Other options include: - Blocking access to port 161 from outside your organisation (using filters on network routers) - Using kernel-level network filtering on the system itself (such as IPTables) - Configuring TCP wrapper support ("--with-libwrap") This uses the TCP 'libwrap' library (available separately) to allow/deny access via /etc/hosts.{allow,deny} For strict security you should use only SNMPv3, which is the secure form of the protocol. However, note that the agent access control mechanisms does not restrict SNMPv3 traffic by location - an SNMPv3 request will be accepted or rejected based purely on the user authentication, irrespective of where it originated. Source-based restrictions on SNMPv3 requests would need to use one of the "external" mechanisms listed above. How can I listen on just one particular interface? ------------------------------------------------- Normally, the agent will bind to the specified port on all interfaces on the system, and accept requests received from any of them. However, if a particular port (or ports) is specified when the agent is first started, then it will only listen for requests on these particular ports. For example: snmpd 127.0.0.1:161 would listen (on the standard port) on the loopback interface only, and: snmpd 10.0.0.1:6161 would listen on port 6161, on the (internal network) interface with address 10.0.0.1. To listen on both of these interfaces (and no others) provide a list of all the desired addresses: snmpd 127.0.0.1:161 127.0.0.1:6161 The AgentX port option ('-x') works in much the same way. The agent is complaining about 'snmpd.conf'. Where is this? ----------------------------------------------------------- It doesn't exist in the distribution as shipped. You need to create it to reflect your local requirement. To get started, you can either just create this file manually, or run snmpconf to help you create one. At the very least, you will need some form of access control configuration, if the agent is to be of any use whatsoever. This can be as simple as: rocommunity public See the snmpd.conf(5) manual page or relevant entries in this FAQ for further details. Why does the agent complain about 'no access control information'? ----------------------------------------------------------------- Although an SNMP agent may support a wide range of management information, it is not necessarily appropriate to report the whole of this to every SNMP management station who asks for it. Some information may be sensitive, and should restricted to authorized administrators only. SNMP therefore includes mechanisms for controlling who has access to what information - both in terms of what can be seen, and (even more importantly) what can be changed. By default, the Net-SNMP agent starts up with a completely empty access control configuration. This means that *no* SNMP request would be successful. It is necessary to explicitly configure suitable access control settings, based on who should be granted access in that particular environment. If there are no access control entries configured (perhaps because no snmpd.conf configuration file has been loaded, or it contains no access control settings), then the agent will not respond to any SNMP requests whatsoever. This is almost certainly not what was intended, so the agent reports this situation. See the next entry for how to configure access control settings. How do I configure access control? --------------------------------- The simplest way is to use the configure directives: rocommunity public (for SNMPv1/2c) rwcommunity private or rouser user1 (for SNMPv3) rwuser user2 These specify the community names or security names to accept for read-only and read-write access to the whole of the supported MIB tree. (Obviously you should change these names to match your requirements - which is a particularly good idea in the case of 'rwcommunity'!) Note that you should *not* specify the same community name for both rocommunity and rwcommunity directives. The rwcommunity setting automatically provides read access, and having both lines (with the same community name) may result in unexpected behaviour. Only use both settings when specifying *different* community names. The same holds true for rouser and rwuser. The two community directives can be restricted to only allow requests from particular sources, and all four can be restricted to a particular subtrees or (from v5.3) a named view. See 'snmpd.conf(5)' for details. How do I configure SNMPv3 users? ------------------------------- There are three ways to configure SNMPv3 users: 1) Stop the agent, and add the line createUser {myUser} MD5 {myPassword} DES to the file /var/net-snmp/snmpd.conf (where {myUser} and {myPassword} are the appropriate values for username and password, _without_ the braces!). Then re-start the snmpd agent. 2) Stop the agent, run the command net-snmp-config --create-snmpv3-user and follow the prompts given. This will create an entry in the /var/net-snmp/snmpd.conf file similar to the above. Then re-start the snmpd agent. 3) Make sure the agent is running, and will respond to an SNMPv3 request (using an existing user with the desired authentication and privacy protocols). Then use the 'snmpusm' command to clone this template user, and change the password. See the access control entries above and the file 'README.snmpv3' for more details about how to use SNMPv3 users, Note that simply having a 'rouser' or 'rwuser' line does *not* automatically create the corresponding SNMPv3 user. You will need the above 'createUser' line (or an equivalent 'usmUser') as well. The 'createUser' line disappears when I start the agent. Why? ------------------------------------------------------------- This is deliberate. The agent removes the (human-readable) 'createUser' directive, and replaces it with an equivalent 'usmUser' entry. This contains the same information, but in a form that's only meaningful internally. Not only is the passphrase no longer visible in the config file, it has actually been converted to a key that is only valid on this particular system. If someone stole the configuration file, they could not use the information from the usmUser entry to access any of your other agents (even if the usernames and passwords were the same). What's the difference between /var/net-snmp and /usr/local/share/snmp? --------------------------------------------------------------------- The /var/net-snmp location is primarily used for information set during the running of the agent, which needs to be persistent between one run of the agent and the next. Apart from "createUser" (see the previous entry), you shouldn't need to touch this file. All other user-provided configuration should go in the traditional location (typically /usr/local/share/snmp/snmpd.conf or /etc/snmp). My new agent is ignoring the old snmpd.conf file. Why? ----------------------------------------------------- The most likely explanation is that the new version of the agent is looking in a different location than the previous one. This is commonly experienced when replacing a ready-installed version (e.g. from a vendor distribution), with the current release installed from the source. Try moving the old config file to the new location, and restart the agent. If you're not sure where this should go, see the next entry. Where should the snmpd.conf file go? ----------------------------------- The default location for this file with the basic distribution is /usr/local/share/snmp/snmpd.conf (or PREFIX/share/snmp/snmpd.conf). Ready-installed versions often look for the file as /etc/snmpd.conf, or /etc/snmp/snmpd.conf. If you are still not sure, try running the command snmpd -f -Le -Dread_config 2>&1 | grep "config path" The first line of output will display the list of locations where the agent is looking for configuration information. Why am I getting "Connection refused"? ------------------------------------- This is actually nothing to do with the access control mechanism (though that's an understandable mistake). This is the result of the TCP wrapper mechanism using the files 'hosts.allow' and 'hosts.deny' to control access to the service. Some distributions may come with this enabled automatically - otherwise you need to explicitly activate this by running configure --with-libwrap and recompiling the agent. If TCP wrappers are enabled, and both hosts.allow and hosts.deny are empty, then all requests will be rejected (with "Connection refused"). The simplest way to avoid this problem and allow incoming requests is to add the line snmpd: ALL to the file /etc/hosts.allow. Be aware that doing this removes one level of protection and allows anyone to try and query your agent. The agent's own access control mechanisms can still be used to restrict what - if anything - they can see. If you do wish to use the TCP wrappers to restrict access, it's sensible to have an explicit entry: snmpd: ALL in the file /etc/hosts.deny, which makes it crystal clear that access to the SNMP agent has been denied. This mechanism can also be used to restrict access to specific management hosts, using a hosts.deny entry such as: snmpd: ALL EXCEPT 127. which will allow connections from localhost, and nothing else. Note that personal firewalls, such as the Linux iptables mechanism, may have a similar effect (though typically this won't be logged). See the earlier entry Requests always seem to timeout, and don't give me anything back. Why? Why can't I see values in the UCDavis 'proc' or 'disk' trees? ------------------------------------------------------------------ Both these trees are designed to report precisely those things that have been explicitly configured for monitoring. If there are no relevant configuration entries in the snmpd.conf file, then these tables will be empty. See the snmpd.conf manual page and the EXAMPLE.conf file for details on configuring the agent. Optionally, run snmpconf -g monitoring to help you set up this section of the snmpd.conf file. Why can't I see values in the UCDavis 'memory' or 'vmstat' trees? ---------------------------------------------------------------- These trees do not need any explicit configuration, and should be present automatically. However the C code necessary to implement these particular MIB modules are not supported on all operating systems. These trees will be omitted on any system for which there is no underlying code. Currently, they are only supported on Linux, HP-UX (memory only), Solaris, BSDi (vmstat on BSDi4 only), Dynix, FreeBSD, NetBSD and OpenBSD. If you want to help port it to other systems, let us know. Note that these subtrees only report the current usage when explicitly queried. They do *not* automatically generate traps when the usage strays outside the configured bounds. See the earlier FAQ entry What traps are sent by the agent? or the snmpd.conf section on active monitoring, for more information. What do the CPU statistics mean - is this the load average? ---------------------------------------------------------- No. Unfortunately, the original definition of the various CPU statistics was a little vague. It referred to a "percentage", without specifying what period this should be calculated over. It was therefore implemented slightly differently on different architectures. The 5.4 release has clarified the situation, and standardised on calculating these percentages over a minute. The relevant MIB descriptions have been updated to make the desired behaviour more explicit. The Net-SNMP agent also includes "raw counters", which can be used to calculate the percentage usage over any desired period. This is the "right" way to handle things in the SNMP model. The original percentage objects have been deprecated, and may possibly be removed in a future release of the agent. Note that this is different from the Unix load average, which is available via the loadTable, and is supported on all architectures. How do I get percentage CPU utilization using ssCpuRawIdle? ----------------------------------------------------------- This one of the "raw counters" mentioned in the previous entry. You need to take two readings of this object and look at the difference between them. That difference divided by the total number of 'ticks' between the two readings (where one tick is probably 0.01 seconds) will give you the percentage utilization over that period. What about multi-processor systems? ---------------------------------- The CPU objects (both percentages and raw counters) were designed to monitor the overall CPU activity of a system, and typically reflect whatever the underlying operating system reports for the (single) CPU statistics information. How these are handled for a multi-CPU system will differ from one O/S to another, and will need to be investigated for each system individually. The htProcessorTable was designed to handle monitoring multi-CPU machines, but the Net-SNMP implementation has up to now treated most systems (with the honourable exception of Solaris, and more recently Linux) as implicitly single-CPU. With the 5.4 release, there is now a cleaner framework for reporting on multi-CPU equipment, and it is hoped that an increasing number of systems will be able to report suitable processor information. Also with the 5.4 release, for the first time the agent will report the hrProcessorLoad value properly, which should provide some simple per-CPU statistics. The speed/type of my network interfaces is wrong - how can I fix it? ------------------------------------------------------------------- Some operating systems will provide a mechanism for determining the speed and type of network interfaces, but many do not. In such cases, the agent attempts to guess the most appropriate values, usually based on the name of the interface. The snmpd.conf directive "interface" allows you to override these guessed values, and provide alternative values for the name, type and speed of a particular interface. This is particularly useful for fast-ethernet, or dial-up interfaces, where the speed cannot be guessed from the name. See the snmpd.conf(5) man page for details. The interface statistics for my subinterfaces are all zero - why? ---------------------------------------------------------------- Unfortunately, most kernels that support multiple logical interfaces on a single physical interface, don't keep separate statistics for each of these. They simply report the overall statistics for the physical interface itself. There's no easy way around this problem - the agent can only report such information as is available. If the kernel doesn't keep track of these figures, the agent can't report them. Sorry! Does the agent support the RMON-MIB? ----------------------------------- Not really. There is an "Rmon" code module included within the agent source code tree, but this is best thought of as a template for the RMON-MIB statistics groups, rather than a full implementation. With most MIBs, the hardest part of implementing the MIB is often getting hold of the data to report. This is definitely true of the RMON-MIB, which relies on gathering (and analysing) a potentially large quantity of network traffic. The Rmon code distributed with the Net-SNMP agent code avoids this problem, by using random data. Some of the functionality of the RMON-MIB, such as the alarm and event groups, has since been superseded by the work of the DisMan IETF working group. The Net-SNMP agent does implement these (more general) MIB modules. But the statistics gathering aspects of the RMON-MIB are not readily available. Note too that none of the core developers have any significant experience with this code, and the person who originally wrote it is no longer active on the mailing lists. So there's no point in asking on the lists whether these modules work or not. You've got the source - how badly do you need this functionality? What does "klread: bad address" mean? ------------------------------------- This means that the agent was unable to extract some of the necessary information from the kernel structures. This is possibly due to: - either looking in the wrong place for kernel information (check the value of KERNEL_LOC) - an error in the implementation of part of the MIB tree for that architecture. Try and identify which OID is generating the error, and contact the list 'net-snmp-coders@lists.sourceforge.net' Remember to tell us what architecture you have! What does "nlist err: wombat not found" (or similar) mean? ---------------------------------------------------------- This means that the agent wasn't able to locate one of the kernel structures it was looking for. This may or may not be important - some systems provide alternative mechanisms for obtaining the necessary information - Solaris, for example, can produce a whole slew of such messages, but still provide the correct information. This error only occurs if you have used the flag '--enable-debugging' as part of the initial configuration. Reconfigure the agent with '--disable-debugging' and these messages will disappear. (It won't fix the underlying problem, but at least you won't be nagged about it). What does "Can't open /dev/kmem" mean? ------------------------------------- This device is normally restricted to just being accessible by root (or possibly by a special group such as 'kmem' or 'sys'). The agent must be able to read this device to obtain the necessary information about the running system. Check that the agent was started by root, and is running with UID 0 (or suitable GID if appropriate). The agent will normally continue to run without this level of access permission, but won't be able to report values for many of the variables (particularly those relating to network statistics). The system uptime (sysUpTime) returned is wrong! ----------------------------------------------- Oh no it's not. The defined meaning of 'sysUpTime' is "the time ... since the *network management* portion of the system was re-initialized." In other words, when the snmp agent was started, not when the system itself last booted. This latter information is available in the Host Resources MIB as "hrSystemUpTime.0" Note that even if the full Host Resources is not supported on your system, it's worth configuring in the system portion using '--with-mib-modules=host/hr_system' and recompiling. This particular group is reasonably likely to work, even if some of the other more architecture-specific groups don't. Can the agent run multi-threaded? -------------------------------- Short answer - no. Longer answer - not easily. Net-SNMP within a single thread of an threaded application is fine, as long as *all* snmp code is kept within the same thread. This lets you add SNMP support to an existing threaded application. If you are concerned with the time taken for to process requests for a particular agent, object or subtree, and you want the agent to continue to respond to other requests in the meantime, there are two options. The first method is using AgentX sub-agents. If you have several tables, each implemented by a separate subagent, then a single request for entries from each of the tables will be processed in parallel (and the agent will continue to respond to other requests while it waits for the subagents to return the necessary information). But a request for several objects from the same table will be passed off to the relevant subagent, where it will (normally) be processed serially. The second method is to use delegated requests + IPC to another process. If takes a long time to retrieve a value for a given object, then the object handler could do whatever necessary to start or communicate with another (non-SNMP) process/thread to actually retrieve the value, and mark the request as delegated. The main agent (or subagent) can then receive and process other requests while waiting for the delegated request to finish. Dealing with resource contention is all up to you. All of this only applies to the GET family of requests. A SET request will block until all pending GET requests have finished, and then will not accept new requests until the SET is complete. Adding full multi-thread support directly to the agent would be nice. We just need someone with time/money to do/sponsor the work. Can I use AgentX (or an embedded SNMP agent) in a threaded application? ----------------------------------------------------------------------- With care. As mentioned in the earlier "thread-safe" FAQ entry, the Net-SNMP agent (including the AgentX subagent) has not been designed for threaded operation. In particular, it makes use of various global variables without attempting to protect them against simultaneous use. This means that it is *NOT* safe to have SNMP or AgentX related processing in two separate threads. This also applies to handling GET (and SET) processing in one thread, and generating traps in another. This is still vulnerable to the usual threading problems. However, as long as *all* of the SNMP-related activity is limited to the one thread, then there should be no reason why this cannot safely communicate with other threads within the same application, using private (thread-safe) mechanisms. But in terms of the Net-SNMP-provided code, the agent (and AgentX subagent) should *not* be regarded as thread-safe. COMPILING ========= How do I control the environment used to compile the software? ------------------------------------------------------------- The basic mechanism for compiling the Net-SNMP project software is to run "configure", followed by "make" (to compile it), "make test" (to check that it's working properly) and then "make install" (to install the files into the correct locations - which typicalyl needs to be done as root. The primary role of "configure" is to determines various aspects about the system that the software is being compiled on. However there are also a number of options to configure which can be used to control various aspects of the compilation environment. The most common options are "--with-mib-modules" and "--with-out-mib-modules" which control the set of MIB module code files that are included within the agent binary. Adding or removing these modules will affect what MIB information the agent can return. See the entry "How do I add a MIB to the agent?" for more details. The configure script can also specify the compiler to use for compiling the source code (e.g. "configure --with-cc=cc"), the flags passed to this compiler (e.g. "configure --with-cflags=-g"), or to the linker (e.g. "configure --with-ldflags=-Bstatic"), and various other aspects of the build environment. Run "configure --help" for a full list. How do I control the environment used to compile the software under Windows? --------------------------------------------------------------------------- If you are compiling the project within the MinGW or Cygwin environments, then these use the same "configure" mechanism as Unix-based systems. See the previous entry for more information. If you are compiling the project from within Visual Studio, then this does not use the standard configure mechanism. Instead, there is a separate "Configure" script within the 'win32' directory. This can be used enable or disable various aspects of the build environment, such as support for encryption or IPv6. Run "Configure --help" for more information Note that this script does not include an equivalent of "--with-mib-modules" for extending the MIB information supported by the agent. Instead, this needs to be done by tweaking the build environment manually. See the file README.win32 for more details of this, and various other aspects of building the project on Windows systems. Why does the compilation complain about missing libraries? --------------------------------------------------------- This has been seen in a number of guises over the years - most commonly on Linux systems (although the problem may also occur elsewhere). The underlying problem is that typical installation may not always include the full set of library links required for building the Net-SNMP software. This problem can usually be fixed by installing the missing packages (typically the development version of a package that is already there). Examples of this that we have come across include: -lelf elfutils-devel (later renamed to elfutils-libelf-devel) -lbz2 bzip2-devel -lselinux libselinux-devel -lcrypto openssl/openssl-devel -lbeecrypt libbeecrypt/beecrypt/beecrypt-devel. These are the names of the RedHat/Fedora RPMs. Other distributions or O/S's may use different names, but the basic idea should be the same. If the compilation is complaining about a missing .so file, then an alternative quick fix is to add the missing symbolic link, using something like: ln -s libelf.so.1 /usr/lib/libelf.so giving the appropriate generic library name from the error message, and the correct number for whichever version of this library you have installed. If the compilation is complaining about a .la file, then you should install the relevant development package, as listed above. How can I reduce the memory footprint? -------------------------------------- In order to reduce the memory footprint (for instance, to embed the snmpd into a device), the following configure options could be used. '--disable-debugging' This turns off the compilation of all debugging statements. '--enable-mini-agent' '--with-out-mib-modules=examples/ucdDemoPublic' This creates an agent with just the essential MIB modules included. NOTE: If you need additional MIB modules, then simply add them using the option '--with-mib-modules=...' but this will of course increase the memory footprint. '--with-transports=UDP' This option specifies the transport domains to include. For a simple standalone agent, just UDP should be sufficient. (Although the 'disman' and 'agentx' modules may require the Callback, TCP and/or Unix transport domains as well). '--without-kmem-usage' This can be used in order to omit the code that operates on the /dev/kmem interface. Clearly, this option cannot be used when one of the configured MIB modules depends on it. '--with-mibdirs=' and '--with-mibs=' These options tell the agent not to load any MIB modules. This doesn't affect the size of libraries or application binaries, but will reduce the memory footprint during runtime. '--disable-mib-loading' This can be used in order to omit the code that loads and parses the MIB files altogether. This will reduce both the runtime memory footprint, and the binary sizes. Once the agent (snmpd) has been linked, you might also try running 'strip snmpd' to remove un-necessary debug/symbol information. How can I reduce the installation footprint or speed up compilation? ------------------------------------------------------------------- The following configure options may also be useful: --disable-agent Do not build the agent (snmpd). --disable-applications Do not build the apps (snmpget, ...). --disable-manuals Do not install the manuals. --disable-scripts Do not install the scripts (mib2c, ...). --disable-mibs Do not install the mib files. --disable-mib-loading Do not include code that parses and manipulates the mib files. How can I compile the project for use on an embedded system? ----------------------------------------------------------- Although this is definitely a Frequently Asked Question on the project mailing lists, it hasn't really been a Frequently _Answered_ Question. The basic problem is that none of the core development team have much involvement or experience with embedded systems. And although we have repeatedly put out a plea for implementation reports and advice, this has not so far been particularly successful. So the first thing to say is that the following suggestions should be treated with a greater than usual level of suspicion. The second thing to say is that compiling the Net-SNMP project for use on an embedded system typically means compiling the *agent* (rather than the trap receiver, or command-line tools). So that is what this entry will concentrate on. There are three main aspects to consider: - how to compile the code, - *what* code to compile, and - how to install the resulting agent binary. The Net-SNMP project uses the standard "configure" mechanism, so the usual cross-compilation options are available - in particular "--host" and "--target". It is also possible to specify the compiler and linker to use ("--with-cc" and "--with-ld"), and any special flags to pass to them ("--with-cflags" and "--with-ldflags"). There shouldn't be anything particularly special about compiling the Net-SNMP code, so see the documentation for your target environment for more information. (And please let us know if there *is* anything special that should be mentioned here!) If the aim is simply to generate an SNMP agent to run on the target system, it's probably not necessary to compile the command-line tools or trap receiver. The configure option "--disable-applications" will omit these elements. See the previous entry for other potentially relevant useful options. Unfortunately, the SNMP agent (and in particular, the code for individual MIB modules) is the most system-specific part of the Net-SNMP software. It may prove necessary to disable particular MIB modules if they do not compile successfully, or attempt to use the wrong system-specific APIs. This can be done using the configure option "--with-out-mib-modules". Alternatively, the option "--enable-mini-agent" will omit all but the core MIB module code. Additional modules can then be added individually using "--with-mib-modules". Further information about how to deal with problems with individual MIB modules is reliant on suitable reports being forthcoming from the wider Net-SNMP community. The ball is in your court! Finally, installing the agent binary is _not_ simply a matter of copying the "snmpd" file onto the target system. The agent typically relies on a number of additional libraries (and possibly the presence of assorted MIB files, unless this has been explicitly omitted). It is normally necessary to run "make install", before copying the installed framework to the target system. If the install destination needs to be different to the eventual location on the target system, this can be handled using the configure options "--prefix" (for the target location) and "--with-install-prefix" (for the temporary install location). Alternatively, this can be handled as part of the install command: make install prefix={target location} INSTALL_PREFIX={temp location} Alternatively, if the agent is compiled with static linking (and no MIB files), then it may be possible to simply copy the agent binary across to the target system. See the next entry for details. How can I compile the project to use static linking? --------------------------------------------------- For totally static net-snmp executables, use configure --with-ldflags=-Bstatic To compile your application with static libraries (eg for easier debugging), and to link to a non-installed build directory, try the following Makefile fragment: NETSNMPDIR=/usr/local/build/snmp/full-clean-cvs-V5-1-patches NETSNMPCONFIG=$(NETSNMPDIR)/net-snmp-config NETSNMPBASECFLAGS := $(shell $(NETSNMPCONFIG) --base-cflags) NETSNMPINCLUDES := $(shell $(NETSNMPCONFIG) --build-includes $(NETSNMPDIR)) # base flags after build/src include, in case it has /usr/local/include NETSNMPCFLAGS=$(NETSNMPINCLUDES) $(NETSNMPBASECFLAGS) NETSNMPBASELIBS := $(shell $(NETSNMPCONFIG) --base-agent-libs) NETSNMPEXTLIBS := $(shell $(NETSNMPCONFIG) --external-agent-libs) NETSNMPLIBDIRS := $(shell $(NETSNMPCONFIG) --build-lib-dirs $(NETSNMPDIR)) NETSNMPLIBDEPS := $(shell $(NETSNMPCONFIG) --build-lib-deps $(NETSNMPDIR)) LIB_DEPS=$(NETSNMPLIBDEPS) LIBS=$(NETSNMPLIBDIRS) -Wl,-Bstatic $(NETSNMPBASELIBS) -Wl,-Bdynamic $(NETSNMPEXTLIBS) STRICT_FLAGS = -Wall -Wstrict-prototypes CFLAGS=-I. $(NETSNMPCFLAGS) $(STRICT_FLAGS) This replaces the standard Makefile section, which will used installed libraries: NETSNMPCONFIG=net-snmp-config # uncomment this if you have GNU make #NETSNMPCFLAGS := $(shell $(NETSNMPCONFIG) --base-cflags) #NETSNMPLIBS := $(shell $(NETSNMPCONFIG) --agent-libs) NETSNMPCFLAGS=`$(NETSNMPCONFIG) --base-cflags` NETSNMPLIBS=`$(NETSNMPCONFIG) --agent-libs` LIBS=$(NETSNMPLIBS) Why does 'make test' skip various tests? --------------------------------------- Some of the tests are only relevant to particular operating systems, or rely on specific areas of functionality. The test framework will check whether the relevant elements are available before running the relevant tests, and will skip them if these modules have been omitted from the build environment (or do not apply to the current system). One example of this are the tests T053agentv1trap, T054agentv2ctrap, T055agentv1mintrap, T056agentv2cmintrap and T113agentxtrap, which rely upon functionality from the NET-SNMP-EXAMPLES-MIB implementation. This module is not included in the default agent configuration, so the test framework will skip these tests. To include them, run "configure --with-mib-modules=examples/example" and re-compile. Why does 'make test' complain about a pid file? ----------------------------------------------- Typically it says something like: cat: cannot open /tmp/snmp-test-1-8694/*pid* It's trying to tell you the port is blocked - typically because another copy of the agent is still running, left over from from a previous testing run. If you type 'ps -ef' you should notice an orphaned process like: snmpd -d -r -U -P /tmp/snmp-test-5-27295/snmpd.pid... Kill this process. This could be happening for several reasons including: 1. You are trying to do concurrent runs of 'make test'. 2. On a slow machine, the agent might be taking too long to start up. Try changing the value of the variable SNMP_SLEEP in testing/RUNTESTS from 1 to something higher - say 3 or 5. CODING ====== How do I write C code to integrate with the agent? ------------------------------------------------- There are three main methods for integrating external C code within the agent. The code can be compiled directly into the agent itself, it can be loaded dynamically while the agent is running, or it can be compiled into a separate application (a "subagent") which communicates with the main master agent. All three approaches have been touched on elsewhere within this FAQ. As far as the module code is concerned, all three mechanisms use exactly the same module API. So a module developed for use directly within the agent, could also be included within a subagent, or loaded dynamically with no (or minimal) code changes needed. Most of this section is concerned with more detailed aspects of developing such code - including the 'mib2c' tool, which can handle generating a basic code framework for implementing a given set of MIB objects. How does the agent fetch the value of a MIB variable from the system? -------------------------------------------------------------------- That's typically the hardest bit of implementing a new MIB module, and is the one thing that 'mib2c' can't help with. It very much depends on the MIB variable concerned (and often the underlying operating system as well). Relatively few MIB modules are completely self-contained, with all the information held internally within the agent, and all updates being done via SNMP requests. Such MIB modules can be implemented fairly easily. More commonly, the agent needs to provide an SNMP-based interface to information held elsewhere, perhaps in the operating system kernel or some other application. Handling this is much more complex - since a lot depends on what mechanisms are provided for retrieving (and possibly updating) this information. The mib2c tool can generate code for processing SNMP requests, based on some internal cache of management information, but it cannot help with populating this cache with the underlying data. That is up to the MIB implementer. See the existing MIB modules in the Net-SNMP source tree for various examples of assorted approaches to this task. Mib2c complains about a missing "mib reference" - what does this mean? --------------------------------------------------------------------- This basically means that it hasn't loaded the MIB file containing the definition of the MIB subtree you're trying to implement. This might be because it hasn't been installed, the name is wrong, or (most likely), because it isn't in the default list. See the MIBS section for more details, or the next entry for suitable invocations of 'mib2c'. Mib2c complains about not having a "valid OID" - what does this mean? --------------------------------------------------------------------- This probably means that you gave it the name of a MIB file (or module), rather than the name of an object defined in that file. Mib2c expects the name of a 'root' object, and will generate a template for the sub-tree starting from there. If you've got a file 'MY-MIB.txt', defining the MIB module 'MY-MIB' which contains a subtree based on the object 'myMib', then you should invoke mib2c as "mib2c .... myMib" rather than "mib2c .... MY-MIB.txt" or "mib2c .... MY-MIB" Note that you'll probably also have to add your MIB to the list of MIBs that are loaded automatically, in order for mib2c to recognise the name of this object. So the command would typically be "MIBS=+MY-MIB mib2c .... myMib" or "MIBS=ALL mib2c .... myMib" Why doesn't mib2c like the MIB file I'm giving it? ------------------------------------------------- This is most likely the same problem as the previous entry. Mib2c takes the name of a MIB _object_, not the name of a file (or MIB module). Try using the name of the MODULE-IDENTITY definition. Another possibility is that the MIB may contain syntax errors. Try running it through 'snmptranslate' or a dedicated SMI validation tool (such as 'smilint' or the on-line interface at http://wwwsnmp.cs.utwente.nl/ietf/mibs/validate/) Mib2c ignores my MIB and generates a pair of 'mib-2' code files. Why? --------------------------------------------------------------------- This is usually a sign of the same problem as the previous entries, giving mib2c the name of the file containing the MIB (or of the MIB itself), rather than an object within it. Earlier versions of mib2c didn't detect this situation, and merrily constructed a template for a default starting point of the mib-2 node. More recent versions complain about not having a valid OID instead. What's the difference between the various mib2c configuration files? ------------------------------------------------------------------- Most of the mib2c config files are concerned with implementing MIB tables, and generate various alternative code templates. These basically fall into four distinct categories. 'mib2c.raw-table.conf' is the lightest of the templates, and just provides a fairly basic table framework. Most of the work of implementing the table - detecting which row is required for a given request, retrieving or updating the relevant column values, and interacting with the underlying subsystem - are all left to the MIB programmer. The second group of templates - 'table_data', 'container' and 'tdata' - all share the same basic model (although the internal details are rather different). The MIB implementer should define a data structure to represent a row of the table, and the helper then takes care of holding the table internally, as a collection of such per-row data structures. This includes identifying which row is required for a given request. Retrieving or updating the appropriate column value is left to the MIB programmer, although the generated framework includes most of the necessary code. Allied to this is a fourth "internal data" mib2c configuration file ('create-dataset') which handles the individual columns as well. This is the closest to a Plug-and-Play configuration, and the MIB implementer only needs to be concerned with any special processing, such as linking the table with the underlying subsystem. The third style of mib2c config assumes that the table data is held externally to the helper - either within the MIB module code itself, or in the external subsystem. The generated code framework includes routines to "iterate" through the rows of the table, with the iterator helper simply deciding which row is required for a particular request. Once again, the MIB programmer must handle retrieving or updating the appropriate column value, although the generated framework includes most of the necessary code. There is a variant of this config ('iterate_access') which works in basically the same way. However this tries to separate out the standard processing, from the code that needs to be amended by the programmer for retrieving and updating the individual column values. This is also the idea behind the final table-oriented mib2c config template - 'mib2c.mfd.conf' (or "MIBs for Dummies"). This is a much more flexible framework, which can be used with either internally held data, or iterating through an external representation. The distinguishing feature of this framework is that it separates out standard and table-specific processing, at a much finer level of detail than the others. The other mib2c config templates are concerned with implementing scalar objects ('scalar', 'int_watch'), code to generating traps ('notify'), and various specialised requirements. There is also a template ('old-api') to generate code suitable for the previous v4 UCD agent - though this is not particularly complete or reliable. It's probably better to use a pure v4 mib2c environment (or switch wholeheartedly to the v5 style). Which mib2c configuration file should I use? ------------------------------------------- The answer to that heavily depends on the characteristics of the MIB objects being implemented. Of the handler-based table frameworks, 'tdata' is more appropriate for tables that can be stored (or a copy cached) within the agent itself, while 'iterate' is more relevant to reporting data from outside the agent. The raw interface is only suitable in very specific circumstances, so it's probably sensible to start with one of the other frameworks first, and only look at this if none of the alternatives seem to work. The decision between the handler-based configs and MfD is more a matter of the style of programming to use. Most of the frameworks define a single handler routine to process an incoming request, so all of the code is listed together, with the MIB programmer inserting table-specific processing into this single block of code. The MfD provides a series of individual object-specific routines, each concerned with one very specific task, and hides as much as possible from the programmer. If you like to understand the broad thrust of what's happening, then one of the handler-based approaches would be the best choice. If you prefer to concentrate on the nitty-gritty of a given table, and are happy to trust that the rest of the processing will work correctly, then the MfD framework would be more appropriate. For implementing a group of scalar objects, then the choice is simple - use 'mib2c.scalar.conf'. Similarly, for generating traps or informs, use 'mib2c.notify.conf'. But note that this only assists with the code to actually generate the trap. It does not address the issue of _when_ to send the trap. See the FAQ entry "How can I get the agent to generate a trap?" for more information. How can I have mib2c generate code for both scalars and tables? -------------------------------------------------------------- This uses a very powerful tool called a "text editor" :-) The mib2c tool uses separate configuration files to generate code for scalar objects, and for tables. This means that it's not possible to automatically generate a single code file that supports both scalars and tables. Instead, the two code files need to be generated separately, and then combined manually. This will typically mean copying the handler routines for the scalar object(s) into the table file, and adding the code to register these handler(s) to the table initialisation routine. Are there any examples, or documentation for developing MIB modules? ------------------------------------------------------------------- Many of the MIB modules shipped with the Net-SNMP agent still use the v4 "traditional" MIB module API, but an increasing number use one of the newer v5 helper-based handlers. All of these can be found under 'agent/mibgroup' The 'tdata' helper is used in the new DisMan Event, Expression and Schedule MIB modules (see 'disman/{event,expr,schedule}/*'). The similar 'dataset' helper is used in the older DisMan Event MIB implementation (see 'disman/mteEvent*') and the Notification Log MIB (see 'notification-log-mib/*'), used by 'snmptrapd' to log incoming traps. The basic iterator handler is used in the TCP and UDP table implementations (mibII/tcpTable & mibII/udpTable), VACM context handling (mibII/vacm_context) and various tables relating to agent internals (agent/*). These show a number of different approaches to using the iterator helper, so it's worth comparing them. The two examples/netSnmpHostsTable* modules provide a contrast between the iterator and iterator_access helpers. There are several examples based on the MfD framework (see '{if,ip,tcp,udp}-mib/'). Much of this code is not intended to be viewed directly, but individual files are clearly commented to distinguish between internal implementation and public code. The Net-SNMP agent does not currently include any MIB modules using the array-user container-based helper. The best examples of this are to be found in the net-policy project. See http://net-policy.sourceforge.net/ Where should I put the files produced by 'mib2c'? ------------------------------------------------ If you're using the main source tree to compile your new module, then put these two files (mymib.[ch]) in the directory 'agent/mibgroup'. You should then re-run configure to add in your new module configure --with-mib-modules=mymib and recompile. If you've got a number of new modules to add, it might be sensible to put them all into a single subdirectory of 'mibgroup'. Then create a header file, listing the individual components. This might look something like: config_require(mymib/myObjects) config_require(mymib/myTable) config_require(mymib/myOtherTable) If this was saved as the file 'mymib.h', then the same configure line given above, would pull in all three modules. See the current contents of 'agent/mibgroup' for examples of this. Note that the MfD framework will generate a similar grouping automatically. Why doesn't my new MIB module report anything? --------------------------------------------- There are probably four main reasons why a new MIB module isn't working. Either it hasn't been included in the running agent, the code is present but hasn't been initialised, the module has been initialised but the handler isn't being called, or there's a problem with the module code itself. To check whether the code files are being compiled, the easiest approach is simply to look at the directory where the code is located. When the agent is compiled, this should produce .o files (and probably .lo files) corresponding to the C code files for this module. Alternatively, run 'nm' (or 'strings') on the MIB module library (libnetsnmpmibs), and look for the names of the initialisation routines or handlers (or the text of any messages displayed by the module code). One other thing to check is whether you have multiple copies of the software installed on the system. This is a particular problem when compiling from source (to include your new module), without first removing any vendor-supplied version of the agent (which won't include this new code). Assuming that you have confirmed that the module code is present in the agent, the next step is to check whether the initialisation routine is being called to register the MIB objects. The simplest way to do this is to include a suitable debugging statement within the initialisation routine, and start the agent with the corresponding '-Dtoken'. Alternatively, try walking the nsModuleName column object, and look for mention of the new MIB module. Assuming the module has been registered, the next step is to check whether the handler is being called, when the agent receives a suitable SNMP request. Again, the simplest way to do this is to include debugging statements within the handler routine, and start the agent with the corresponding '-Dtoken'. Then issue an "snmpget" request for an instance within the new MIB module. (This command is preferable to the usual "snmpwalk" command, as it is more closely focused on the MIB module in question). If this indicates that the handler routine isn't being called, then there are two main likely causes. Firstly, check the access control settings. If these are configured to block access to this portion of the OID tree, then the MIB handler will never be called. Secondly, several of the table helpers are designed to know which rows of the table are valid, and will call the main MIB handler with information about the relevant row. If the requested row is not valid (or the table is empty), then the handler will not be called. Finally, if the handler _is_ being called, but is still not returning any information, then the cause probably lies with your MIB module code. In which case, it's really up to you to find the problem and fix it! Either activate any debugging code that you have included within the handler routine, or run the agent under a source code debugger, and step through the handler processing. In either case, it's much easier to debug these problems when processing an "snmpget" request, rather than "snmpgetnext" or "snmpwalk". Remember that 'mib2c' simply generates template code for your MIB module. It's up to you to fill in the details, to report the actual information from whatever underlying subsystem is being monitored. Mib2c cannot help with the semantics of the MIB module - it's purely there to provide an initial code framework, based on the _syntax_ of the MIB module objects. Why does the iterator call my get_{first,next} routines so often? ----------------------------------------------------------------------- The first thing to realise is that the 'get_first' and 'get_next' hook routines are concerned with processing a single SNMP request, not with walking the whole table. A full "snmpwalk" command will typically involve a series of individual 'GetNext' requests, and every one of these will trigger a separate 'get_first/get_next/get_next/....' cycle. It's usually more efficient to use 'snmptable' which will walk each column in parallel (as well as displaying the results in a more natural manner). Secondly, the iterator helper was originally designed to handle unsorted data, so will look at every row of the internal table for each request. If the data is actually held in the correct order, then it's worth setting the NETSNMP_ITERATOR_FLAG_SORTED flag: iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info); iinfo->flags |= NETSNMP_ITERATOR_FLAG_SORTED; This will help the situation somewhat. But the iterator helper is inherently a relatively inefficient mechanism, and it may be worth looking at one of the other helpers, particularly if the data will be held within the agent itself. How can I get the agent to generate a trap (or inform)? ------------------------------------------------------ There are two aspects to having the agent generate a trap - knowing *how* to do this, and knowing *when* to do so. Actually generating a trap is reasonably simple - just call one of the trap API routines ('send_easy_trap()' or 'send_v2trap()') with the relevant information (generic and specific trap values, or a varbind list respectively). The 'mib2c.notify.conf' configuration file can be used to construct a suitable template routine for generating a trap, including building the variable list from the MIB trap definition. These variables can then be given suitable values, before invoking the 'send_v2trap()' call to actually send the trap. See the 'snmp_trap_api(3)' man page for further details. Note that these APIs are only available within the agent (or subagents), and are not available to stand-alone applications. The code for 'snmptrap' shows an approach to use in such a case. Determining *when* to generate the trap (either directly or via the mib2c-generated routine) is often harder. If the trap is generated in response to some action within the agent, (e.g. as the result of a SET), then this isn't too much of a problem. But if the trap is intended to report on a change of status (e.g. a network interface going up or down, or a disk filling up), then actually detecting this is non-trivial. Unless the underlying system can signal this situation to the agent, then it's typically necessary to poll the value(s) on a regular basis, save the results and compare them with the new values the next time round. The simplest way to handle this is via the DisMan Event MIB, which is designed for exactly this purpose. As long as you can specify a MIB object to monitor, and the value or thresholds that should trigger a notification, then this module can check these values regularly, and automatically send a suitable trap when appropriate. See the 'snmpd.conf(5)' man page (under ACTIVE MONITORING) for details. Otherwise, you'd need to use the routines documented in 'snmp_alarm(3)' to regularly invoke a monitoring routine. This would check the necessary conditions (which need not be MIB objects), and call the 'send_xxx_trap()' routine (as generated by 'mib2c.notify.conf') when appropriate. How can I get an AgentX sub-agent to generate a trap (or inform)? ---------------------------------------------------------------- This is done in exactly the same manner as with the main SNMP agent. Calling one of the routines described in 'snmp_trap_api(3)' will cause the AgentX sub-agent to send a notification to the master agent, which will then pass this on to the configured trap destination(s). One of the original design aims of the Net-SNMP AgentX support was that the agent (or subagent) framework should be transparent to a MIB module implementer. The interface between the agent framework and a MIB module should be independent of the protocol used to receive the original request. So the exact same MIB module code could be used within a traditional SNMP-only agent, or an AgentX subagent, with no changes needed. This also holds for sending traps. How can I get the agent to send an SNMPv1 (or SNMPv2c) trap? ----------------------------------------------------------- It doesn't make any difference whether you use the v1-style API call 'send_easy_trap()' or the v2-style 'send_v2trap()'. What matters is the directive(s) in the snmpd.conf file. If this file contains 'trapsink', then the agent will send an SNMPv1 trap. If this file contains 'trap2sink', then the agent will send an SNMPv2c trap. And if this file contains both, then the agent will send *two* copies of this trap. See the entry Where are these traps sent to? in the AGENT section for details. How can I get the agent to include varbinds with an SNMPv1 trap? --------------------------------------------------------------- There are two ways to do this. You can either use the 'send_v2trap()' call and give a varbind list, starting with the v2-equivalent of the SNMPv1 trap, followed by the additional varbinds. Alternatively, you can use the API call 'send_trap_vars()' which takes the same generic/specific trap values as 'send_easy_trap()', plus the list of additional varbinds. In either case, you also need to have 'trapsink' in the snmpd.conf file. The resulting trap will be identical, whichever approach is used. How can I get the agent to send an SNMPv1 enterprise-specific trap? ------------------------------------------------------------------ There are two ways to do this. You can either use the 'send_v2trap()' call and give a varbind list, starting with the v2-equivalent of the SNMPv1 trap, followed by the additional varbinds. Alternatively, you can use the (undocumented) API call 'send_enterprise_trap_vars()' which takes the same parameters as 'send_trap_vars()', plus the enterprise OID to use (in the usual name/length form). See the code file 'agent_trap.c' In either case, you also need to have 'trapsink' in the snmpd.conf file. The resulting trap will be identical, whichever approach is used. How can I get the agent to send an SNMPv3 trap (or inform)? ---------------------------------------------------------- It doesn't matter which API call you use to specify the trap - 'send_easy_trap()', 'send_v2trap()' or one of the other calls mentioned above. Generating an SNMPv3 notification (rather than a community-based one) is controlled by the snmpd.conf file. To send an SNMPv3 trap, this file should contain a 'snmpsess' directive, specifying the version, security level, user name and passphrases (if applicable), as well as the destination address. This is basically the same as the command line required for sending the trap manually, using 'snmptrap'. Note that (unlike 'snmptrap') this directive does *not* read default settings from an 'snmp.conf' file, so these must be specified explicitly in the 'snmpsess' line. Why does calling 'send_v2trap' generate an SNMPv1 trap (or vice versa)? ---------------------------------------------------------------------- The two versions of the trap API calls are concerned with how the trap is represented when it is passed *in* to the API, not the version of the trap PDU that will actually be generated by the agent. That is determined by the configuration token used to set up the trap destination. Remember that in general, all traps are sent to all destinations. This means that a trap specified using the SNMPv1 trap syntax needs to be converted to the SNMPv2 format before it can be sent to an SNMPv2 (or SNMPv3) destination. Similarly, a trap specified using the SNMPv2 syntax needs to be converted to the SNMPv1 format before it can be sent to an SNMPv1 sink. Essentially, the API call to use depends on what you asking for, which is not necessarily what the recipients will actually get! See 'snmp_trap_api(3)' for a fuller explanation. How can I register a MIB module in a different (SNMPv3) context? --------------------------------------------------------------- Contexts are a mechanism within SNMPv3 (and AgentX) whereby an agent can support parallel versions of the same MIB objects, referring to different underlying data sets. By default, a MIB module registrations will use the default empty context of "". But it's also possible to provide MIB information using a different (non-default) context. There are three aspects involved in doing this. Firsly, it's necessary to register the MIB module in this non-default context. With the v4 API, this uses the call 'register_mib_context()' rather than the REGISTER_MIB macro. This is significantly more detailed, but most of the additional parameters can take fixed values, if all that's needed is to change the registration context. Instead of the macro call: REGISTER_MIB("my_token", my_variables, variable1, my_variables_oid); use the function call: register_mib_context( "my_token", my_variables, sizeof(variable1), sizeof(my_variables)/sizeof(variable1), my_variables_oid, sizeof(my_variables_oid)/sizeof(oid), DEFAULT_MIB_PRIORITY, 0, 0, NULL, "my_context", -1, 0); Things are much easier with the v5 helper-based API. Having created the registration structure, this just requires setting the 'contextName' field before actually registering the MIB module: netsnmp_handler_registration *reg; reg = netsnmp_create_handler_registration(.....); reg->contextName = strdup("my_context"); netsnmp_register_handler(reg); Secondly, it is necessary to configure the access control settings to allow access to information in the new context. This is handled automatically when using the simple "rouser" or "rwuser" directives. But if access control is configured using the fuller com2sec/group/view/access mechanism, then the "access" line must specify the appropriate context(s), either explicitly: access {group} "my_context" any noauth exact ...... or using a single entry to cover all possible contexts: access {group} "" any noauth prefix ...... Finally, the SNMP request used to retrieve (or update) the information must also specify the required context. With SNMPv3 requests, the context is part of the protocol, so this can be done using a command-line option: snmpwalk -v 3 -n my_context ..... With community-based requests (SNMPv1 and SNMPv2c), things aren't so simple. Although the "rocommunity" and "rwcommunity" settings also configure access for all possible contexts, there's no way to specify a non-default context as part of the request. The only way to handle non-default contexts with community-based SNMP requests is to set up a mapping from the community string to the desired context. This uses the "com2sec" directive, with an additional "-Cn" parameter. Note that this also means that the access control must be configured using the full com2sec/group/view/access mechanism. The short-form access control directives do not handle the mapping of community strings to non-default contexts. MISC ====== What ASN.1 parser is used? ------------------------- The parser used by both the agent and client programs is coded by hand. This parser has recently been re-vamped to allow control of which of the available MIBs should be included, and to handle duplicate object subidentifiers. The source code can be found in the snmplib directory (in 'parse.c'), and the parser is usually bundled into the library 'libnetsnmp.a' Note that the parser attempts to be fairly forgiving of some common errors and incompatibilities in MIB files. The Net-SNMP tools accepting a MIB file without complaint does *not* imply that the MIB is strictly correct. Certain MIBs may need some amendments to allow them to be read correctly by the parser. Contact the coders' list for advice. What is the Official Slogan of the net-snmp-coders list? ------------------------------------------------------- "The current implementation is non-obvious and may need to be improved." (with thanks to Rohit Dube) And an alternate, added 26-Apr-2000: "In theory, it shouldn't be that hard, but it just needs to be done." usr/share/doc/libidn/FAQ000064400000004206152532465670011040 0ustar00Libidn FAQ -- Anticipated Frequently Asked Questions. Copyright (C) 2002-2016 Simon Josefsson See the end for copying conditions. Q#1: Why doesn't Libidn use a separate library for the Unicode operations? A#1: Separate libraries (Glib, QT, libiconv) seldom mark the Unicode tables with the corresponding Unicode version they implement, nor do they provide a interface where a specific version can be requested. This violates the stringprep specification which requires that a specific version must be used. Also, some of these third party libraries depend on non-portable behavior (e.g. threads). Q#2: Why do Libidn include several stringprep profiles? They waste space! A#2: The stringprep profiles included are usually derived from the generic stringprep tables, and doesn't waste more than say a few hundred bytes (see profiles.c). The Unicode normalization tables and the generic stringprep tables are roughly equivalent in size, although the latter tables can surely be compressed much further. They occupy about 100 kilobytes on typical platforms. However, if in the future several large Stringprep profiles are added, configure options will be added to help reduce size. Q#3: I thought GNU was encouraging libraries to be licensed under the GPL? A#3: The reasoning for this was for libraries that provide unique functionality to encourage more free programs. Since there are several IDN libraries out there, using the GPL for Libidn would only encourage people not to use Libidn which would not help the spread of free software. Q#4: How do I add a new stringprep profile? A#4: Add the profile definition to profiles.c, export the symbol and optionally add a CPP macro in stringprep.h (and document it in stringprep.c). If you want to add self tests, do it through tst_stringprep.c. Mention it in NEWS. ---------------------------------------------------------------------- Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright notice and this notice are preserved. usr/share/doc/cpanel-pure-ftpd/FAQ000064400000077447152532537350012761 0ustar00 FREQUENTLY ASKED QUESTIONS -------------------------------------------------- * Users can delete root-owned files? -> I have a directory owned by 'john', but I've put some files owned by 'root' (or another user) in it. However, I noticed that John can delete these files! Yes, this is the standard Unix behavior: the owner of a directory can do whatever he likes to do in his directory, regardless of who owns the file in it. If you want to have immutable files, check for such a feature in your operating system. For instance, on Linux filesystems, "chattr +i " does the trick. On BSD systems, try "chflags schg " . * Directories shared by multiple users. -> I have a "public" directory. All users can download and upload files from/to this directory. Permissions are 777 on it. But user 'john' can delete files owned by user 'joe'. How to prevent this? Put the sticky bit on that directory: chmod 1777 public. That way, the directory remains public (read/write), but people can only delete files they own. * Restricting directory visibility. -> I want that people only see their home directory and their own files. I don't want them to look at my systems files. This feature is called "chroot". You can enable this by running pure-ftpd with the "-A" switch to do this with ALL your users (but root) . You can alternatively use "-a " to have a "trusted group". Everyone will be caged, EXCEPT members of that group. Don't use -a and -A together. Another way is to selectively choose what users you want to chroot. This can be done with the /./ trick (see the README file about this) or with virtual users. * Shared directories and chroot. -> I have a directory, say /var/incoming, that I want to be shared by every user. But I want my users to be chrooted. So /var/incoming should be visible in 'joe' and 'john' accounts, but those are chrooted. So, how to have the content of /var/incoming visible in these accounts? Making a symbolic link won't work, because when you are chrooted, it means that everything outside a base directory (your user's home directory) won't be reachable, even though a symbolic link. But all modern operating systems can mount local directories to several locations. To have an exact duplicate of your /var/incoming directory available in /home/john/incoming and /home/joe/incoming, use one of these commands: * Linux : mount --bind /var/incoming /home/john/incoming mount --bind /var/incoming /home/joe/incoming * Solaris : mount -F lofs /var/incoming /home/john/incoming mount -F lofs /var/incoming /home/joe/incoming * FreeBSD : mount_null /var/incoming /home/john/incoming mount_null /var/incoming /home/joe/incoming Another alternative is to compile Pure-FTPd with --with-virtualchroot as a ./configure option. With virtual chroot, symbolic links pointing outside a chroot jail *are* followed. Binary packages are compiled with this feature turned on. * Tar and/or gzip on the fly -> Is it possible to use a command like "get directory.tar" as with Wu-FTPd ? (Sven Goldt) Unfortunately, no. Server-side gzip/tar creation is not a present nor a planned feature. It has been responsible of severe security flaws in Wu-ftpd and BSD ftpd, it can take a lot of server resource (denial-of-service) and it's a pain to set up (chrooted environment => need to add /etc /lib /bin directories, /dev on some platforms, etc) . * How to restrict access to dot files ? -> Is there an option to prevent people from accessing "." files/dirs (such as .bash_history, .profile, .ssh ...) EVEN if they are owned by the user ? (William Kern) Yes. '-x' (--prohibitdotfileswrite) denies write/delete/chmod/rename of dot-files, even if they are owned by the user. They can be listed, though, because security through obscurity is dumb and software shouldn't lie to you. But users can't change the content of these files. Alternatively, you can use '-X' (--prohibitdotfilesread) to also prevent users from READING these files and going into directories that begin with "." . * Log files -> Where does logging info go ? How to redirect it to a specific file ? How to suppress logging ? Log messages are sent to the syslog daemon. The syslog daemon is often called syslogd or syslog-ng. He's in charge of dispatching logging events from various programs to log files, according to a "facility" (category) and a "priority" (urgency: debug, info, warning, error, critical...) . Pure-FTPd logging messages are send with the "ftp" facility by default (or "local2" on some older systems without the "ftp" facility) . Unless you told the syslogd to redirect messages with the "ftp" facility to a specific file, the messages will be merged into /var/adm/messages, /var/log/messages, /var/adm/syslog or /var/log/syslog. Check /etc/syslogd.conf. You should have a line like: *.*;mail.none;news.none -/var/log/messages just add ftp.none: *.*;ftp.none;mail.none;news.none -/var/log/messages And if you want FTP info go in a specific file, just add: ftp.* /var/log/ftp and all FTP messages will go in /var/log/ftp . And only there. The facility can be changed if you add the -f option to pure-ftpd (or --facility=) . To completely disable logging, use -f none (or --facility=none) . If you don't read your log files, it's recommended: it will improve performance and reduce disk I/O. * How to prevent your partitions to be filled -> Is it possible to forbid new uploads when the disk is almost full ? (Cyberic) Use the "-k" (--maxdiskusagepct) flag. If you add -k 95 , no new upload can occur if your partition if more than 95% full. * Firewalling -> My FTP server is behind a firewall. What ports should I open? First, you have to open port 21 TO the FTP server. You also have to allow connections FROM (not to) ports <= 20 (of the FTP server) to everywhere. That's enough to handle the "active" mode. But that's not enough to handle all types of clients. Most clients will use another mode to transmit data called 'passive' mode. It's a bit more secure than 'active' mode, but you need to open more ports on your firewall to have it work. So, open some ports TO the FTP server. These ports should be > 1023. It's recommended to use at least twice the max number of clients you are expecting. So, if you accept 200 concurrent sessions, opening ports 50000 to 50400 is ok. Then, run pure-ftpd with the '-p' switch followed by the range configured in your firewall. Example: /usr/local/sbin/pure-ftpd -p 50000:50400 & Unlike some popular belief, the MORE opened ports you have for passive FTP, the MORE your FTP server will be secure, because the LESS you are vulnerable to data hijacking. If your firewall also does network translation (NAT), you have to enable port forwarding for all passive ports. On the client side, if a client if behind a firewall, that firewall must understand the FTP protocol. On Linux firewalls (iptables), just load the ip_conntrack_ftp and ip_nat_ftp modules. On OpenBSD, ISOS and FreeBSD 5 firewalls (PF), redirect all traffic to port 21, to ftp-proxy. * Unable to log in (unix authentication) -> I'm using simple Unix authentication. No PAM, no puredb, no MySQL, no LDAP. Anonymous FTP works, but I can't log in as any other user. It keeps saying "authentication failed". To log in, the shell assigned to your users must be listed in the /etc/shells file. The exact path should be there, even for fake shells like /etc or /bin/true. Also double check that you have a carriage return after the last line in /etc/shells. * Network filesystems. -> I have a strange problem on Linux or FreeBSD. Uploading a file works fine, but downloading a file only create 0-byte files. On the server, these files are on NFS/Novell shares/Appletalk shares/Coda/Intermezzo/SMB volumes. By default, pure-ftpd uses zero-copy networking in order to increase throughput and reduce the CPU load. But zero-copy doesn't work with all filesystems, especially network filesystems. You have to disable zero-copy if you want to serve files from a network FS or from a TMPFS virtual disk. To disable zero-copy, recompile pure-ftpd with ./configure --without-sendfile * Solaris and chroot. -> When I ftp to my Solaris server, I get this as an answer to 'ls': "425 Can't create the data socket: Bad file number." On Solaris, to get chroot to work with pure-ftpd you need a dev directory in your new rootdir with these: crw-rw-rw- 1 root other 11, 42 Dec 10 15:02 tcp crw-rw-rw- 1 root other 105, 1 Dec 10 15:02 ticotsord crw-rw-rw- 1 root other 11, 41 Dec 10 15:03 udp crw-rw-rw- 1 root other 13, 12 Dec 10 15:03 zero (Reported by Kenneth Stailey) * Upgrading. -> Can anyone explain how to update Pureftpd (from source), without having to change all my settings etc. (Simon H) 1) get the source code and unpack it. 2) ./configure it with your favorite options 3) make 4) rm -f /usr/local/sbin/pure-ftpd 5) make install-strip 6) if you run pure-ftpd from inetd,tcpserver,xinetd, etc: nothing left to do. You have it upgraded. 7) if you run it standalone, stop the server: kill $(cat /var/run/pure-ftpd.pid) then launch it again: /usr/local/sbin/pure-ftpd & * FTP over SSH. -> How to run Pure-FTPd over SSH? I want to encrypt all connection data (including passwords) . FTP-over-SSH is a nice alternative over FTP-over-TLS (impossible to securely firewall) and SFTP (which is slower, but only uses one port) . Customers using Windows can use FTP-over-SSH with the excellent Van Dyke's SecureFX client (http://www.vandyke.com) . It doesn't require any special knowledge: just tell your customer to check "FTP-over-SSH2" in the "Protocol" listbox when creating an account for your FTP server. On the server side, here's how to manage FTP-over-SSH accounts: 1) Add /usr/bin/false to your /etc/shells file (on some systems, it's /bin/false) . 2) To create a FTP-over-SSH account, create a system account with /dev/null as a home directory and /usr/bin/false as a shell. You don't need a dedicated uid: the same uid can be reused for every FTP-over-SSH account. 3) Create a virtual user account for that user (either with PureDB, SQL or LDAP) . Give that virtual user a real home directory and only allow connections coming from 127.0.0.1 (all FTP-over-SSH sessions will come from localhost, due to SSH tunneling) . People with no home directory (/dev/null) and no valid shell (/usr/bin/false) won't be able to get a shell nor to run any command on your server. But they will be granted FTP-over-SSH sessions. Here are examples (Linux/OpenBSD/ISOS commands, translate them if necessary) . 1) Creating a regular FTP account: pure-pw useradd customer1 -m -d /home/customer1 -u ftpuser 2) Creating a FTP-over-SSH account (non-encrypted sessions are denied): useradd -u ftpuser -g ftpgroup -d /dev/null -s /usr/bin/false customer2 pure-pw useradd customer2 -m -d /home/customer2 -u ftpuser -r 127.0.0.1/32 3) Creating an account who can use regular (unencrypted) FTP from the internal network (192.168.1.x), but who must use FTP-over-SSH when coming from an external network (internet): useradd -u ftpuser -g ftpgroup -d /dev/null -s /usr/bin/false customer3 pure-pw useradd customer3 -m -d /home/customer3 -u ftpuser \ -r 127.0.0.1/32,192.168.1.0/24 * Virtual users: /etc/pureftpd.pdb . -> I made changes to /etc/pureftpd.passwd but the server doesn't understand them: I can't access any account I just created. The server never reads /etc/pureftpd.passwd directly. Instead, it reads /etc/pureftpd.pdb (or whatever file name you gave after -lpuredb:...) . This file is a copy of /etc/pureftpd.passwd, but in a binary format, optimized for fast lookups. After having made a manual change to /etc/pureftpd.passwd, you must rebuild /etc/pureftpd.pdb with the following commands: pure-pw mkdb If you add/delete/modify user accounts with pure-pw useradd/usermod/userdel/ passwd, don't forget the '-m' option to automatically rebuild /etc/pureftpd.pdb and not only update /etc/pureftpd.passwd . * Giving access to dot-files. -> I don't want my users to read files beginning with a dot. Except one file I'd like to give 'John' read (and maybe write) access to. Create a symbolic link in John's account, pointing to the dot-file. Example: ln -s .bashrc bashrc John will be able to access ".bashrc" through the symbolic link, "bashrc". * Initial banner. -> How do I display a customized message before the login prompt? Compile with --with-cookie and run the server with -F . In that file, put a nice customized banner message. * Internet Explorer. -> Internet Explorer doesn't show any login box. IE does a very strange trick to detect whether an FTP server does accept anonymous connections or not. Basically, it connects to the server and logs in as 'anonymous'. But if you say 'no' at this point, it drops the connections with an error. You have to say 'ok, anonymous users are allowed' and then, when a dummy password ('IE@') is sent, you say 'ah ehm... finally... no... anonymous users aren't allowed' . Silly. To play that game, you must run pure-ftpd with the -E (non-anonymous server) and -b (compatibility with broken clients) flags. Then, the magic popup will show up. But please note that IE (and browsers at large) are usually bad FTP clients. -> Internet Explorer doesn't want to log in. (Matthew Enger) Check that the max number of connections (either per user or per IP) is at least 2. IE needs two connections to connect to an FTP server. * Passwords and pure-pw scripting. -> I would like to create virtual users with a shell-script. if i us pure-pw useradd ..... it always asks for the new password. is there any command-line option which tells pure-pw the password (like useradd ftp-user ftp-password -m) ? (at1ce) . Giving cleartext (and badly one-way hashed) passwords through command-line switches is a bad idea. Because users could issue a simple 'ps' command and discover these passwords. One way to enter a password (not from the keyboard) is to put the password twice in a temporary file, then redirect that file to stdin. Example: pure-pw useradd john -d /tmp/john -u ftpuser -m < ~/tmp/passfile And in ~/tmp/passfile, have something like: john's password john's password If you really need to avoid a temporary file and if nobody but you can log on the machine, you can always do this: (echo blahblah; echo blahblah) | pure-pw useradd john -d /tmp/john -u ftpuser * Altlog and pure-uploadscript don't work. -> pure-uploadscript doesn't run anything. Alternative logging methods (CLF, stats, W3C...) create a logfile, but it always stays empty. Maybe your operating system has a buggy realpath() implementation. Some old Solaris and Linux versions are known to have such a bug. Try to recompile pure-ftpd, but run ./configure with the --with-brokenrealpath switch first. * The server starts, but doesn't listen to any port? -> The server is properly running, I see it in the process list, but any try to connect to the configured port (or port 21 by default) fails. The socket isn't even open. Check two things : - If you are running a BSD system and you want to listen to IPv4 addresses, check that the "-4" switch ("IPV4Only" in config file) is enabled. - If you upload script are enabled ("-o", or "CallUploadScript"), make sure that the pure-uploadscript is started. Or the FTP server will actually wait until pure-uploadscript is actually ready to process new uploads. If you don't need the uploadscript facility, remove "-o". * Double slash. -> Why do I see double slashes in log files? For instance, the path of a downloaded file looks like /home/john//pictures/zok.jpg . '//' is a symbol for the limit of the chroot jail. In that example, it means that John is caged in /home/john/ . * ftpwho as a non-root user. -> How do I give access to the 'pure-ftpwho' command to non-root users? The 'pure-ftpwho' command is restricted to root by default, because users probably shouldn't be given the ability to spy what other users are doing on the same host. However, it's safe to put the setuid bit on that command, in order to have it work as any user: chmod 4711 /usr/local/sbin/pure-ftpwho * Changing bandwidth throttling on-the-fly. -> Is it possible to change the bandwidth allocated to a user during a transfer, so that the change takes place immediately? Unfortunately, no. Or at least not at pure-ftpd level. Doing so would need to re-read user's parameters all the time and it would be horribly slow. Other mechanisms would work, like signals to interrupt transfers, re-read parameters, then resume. But it would introduce a lot of complexity to the code. If you're using a modern operating system like OpenBSD, ISOS or Linux, your kernel already includes a fair TCP/IP traffic shaper. And because it works at kernel-level, you can easily change the bandwidth allowed to IPs or services on-the-fly. Have a look at pf.conf(5) OpenBSD, ISOS and FreeBSD 5, and at tc (or read the Linux networking HOWTO) on Linux. Also see the 'Global bandwidth limitation' section later in this document. * KERBEROS_V4 rejected as an authentication type. -> It works and I can log in, but I receive these strange error messages at log in, even in a non-chrooted environment: 220 FTP server ready. 502 Security extensions not implemented 502 Security extensions not implemented KERBEROS_V4 rejected as an authentication type Why and what do they mean? This is a Linux-specific instllation issue. It means that your command-line FTP client isn't a normal one, but a Kerberos FTP client. You probably installed RPMs for Kerberos, although you don't use it. These messages are harmless as Kerberos clients will fallback to normal FTP (after these errors), but you just have to deinstall Kerberos on your client host to have 'ftp' work without these messages. * Wrong group ownership. -> I have a user called 'john' whose group is 'johngroup'. When John uploads a file, that one belongs to 'john', but to another group like 'wheel' (whose John isn't a member of). What's wrong? This is a BSD standard behavior (verified on OpenBSD, ISOS, DragonflyBSD and FreeBSD): when a new file is created, the group is inherited from the parent directory. On other systems (like GNU/Linux), files are owned by the primary group of the user, unless the directory has the setgid bit set. If you want new files uploaded in John's directory to belong to group 'johngroup', have that directory (and probably also subdirectories) belong to 'johngroup': chgrp -R johngroup /home/john * Compilation with MySQL. -> I can't compile with MySQL. ./configure says that MySQL libraries aren't properly installed. The libmysqlclient.so file should be in a path known by your dynamic linker. For instance, on a GNU/Linux system, add the path to libmysqlclient.so file (only the path, not the file itself) to /etc/ld.so.conf . Then, run 'ldconfig' . * "Sorry, I can't trust you". -> When a user tries to log in, he gets "Sorry, I can't trust you". But his login/password pair is right. What wrong? That message can means two things: - The user has a shell that isn't listed in /etc/shells. You must add it, even if it's a fake shell like /bin/false . Also make sure that you have a carriage return after the last entry in /etc/shells. - You are using the -u option to deny access to users whose uid is below . But the user you are trying to log in as, has an uid in the forbidden range. * Customer-friendly configuration. -> What switches do you recommend to start the server, for an hosting service? Here's a good start: --chrooteveryone \ --maxclientsperip=5 \ --displaydotfiles \ --noanonymous \ --minuid=100 \ --umask=022:022 \ --limitrecursion=10000:3 \ --customerproof * Anonymous FTP with virtual users. -> I successfully created a virtual user called 'ftp' or 'anonymous', but anonymous FTP doesn't work. Pure-FTPd never fetch any info from the virtual users backends (puredb, MySQL, LDAP, etc) for anonymous sessions. There are three reasons not to do so: - Speed: do we need to query a database just to get the anonymous user's home directory? We don't need to retrieve any password for anonymous sessions. - Consistency: with the virtual hosting mechanism. To run an anonymous FTP server you must have a *system* account called 'ftp'. Don't give it any valid shell, just a home directory. That home directory is the anonymous area. * A basic setup. -> I'm trying to set up a ftp server just for me and my family so we can get and upload files when on the road. How can I make two users, say Jane and Joe, who share the directory /home/ftp and /home/ftp/incoming. In /home/ftp they only have read privs. and in /home/ftp/incoming they have read and write privs. Add a group for all FTP users (not mandatory, but more secure): groupadd ftpgroup Add an uid for all FTP users (idem, not mandatory, but better): useradd -g ftpgroup -d /dev/null -s /etc ftpuser Now, let's create /home/ftp and /home/ftp/incoming: mkdir -p /home/ftp/incoming chown -R root:ftpgroup /home/ftp/incoming chmod -R 755 /home/ftp chmod -R 1775 /home/ftp/incoming Let's add Jane: pure-pw useradd jane -m -u ftpuser -d /home/ftp Let's add Joe: pure-pw useradd joe -m -u ftpuser -d /home/ftp Let's start the FTP server: /usr/local/sbin/pure-ftpd -lpuredb:/etc/pureftpd.pdb -H -B Everything should be ok now. For more info about how to create new users, change passwords, etc.: http://www.pureftpd.org/README.Virtual-Users * Slow pure-ftpwho or slow login. -> Sometimes, pure-ftpwho is slow to show the result. And sometimes, when an user logs in, the session stucks a bit before he can get a directory listing. This is probably caused by a slow DNS resolver. In order to display full host names, pure-ftpd has indeed to make DNS queries that can be slow if you link is slow, or if the client link is slow. You can speed up pure-ftpwho and pure-ftpd with the -H switch. Names won't be resolved, you will see IP addresses instead. * Chrooted users can follow symlinks outside the chroot jail? -> People can create symbolic links to '/' and escape their home directory! There are two chroot implementations in pure-ftpd: - The traditional one, based upon your kernel chroot() system call. This is the default. With that one, symbolic links can only point inside the chroot jail, or they won't be followed. - The 'virtual chroot' implementation. With that feature, users *can* follow all symbolic links, even when they don't point inside the jail. This is very handy to set up directories shared by multiple users. Binary packages are compiled with virtual chroot by default. To enable the virtual chroot feature when you are compiling the server, use the --with-virtualchroot with ./configure . If you want a restricted chroot, don't include --with-virtualchroot. Please note that the FTP server will never let people create new symbolic links. Symbolic links have to be already there to be followed. Or if your users can create symbolic links through Perl or PHP scripts, your hosting platform is really badly configured. People can install any web file browser, they don't need FTP to look at your system files. Recompile PHP without POSIX functions and run all Perl scripts chrooted. * How to start Pure-FTPd in background. -> I start 'pure-ftpd' from an X terminal and the server properly answers. However, as soon as I close the terminal, the server stops. This is a shell dependent issue. Your shell is configured to close all background jobs when leaving. You can change your shell options (probably with a 'set' directive) or detach background jobs with the 'disown' keyword. Alternatively, you can just start pure-ftpd with the -B switch in order to have it detach at startup time: /usr/local/sbin/pure-ftpd -B * Windows command-line FTP client and 'ls'. -> With the command-line Windows FTP client, 'ls -la' doesn't return any file. The 'ls' command of an FTP client has nothing to do with the 'ls' command started from an Unix shell. With the command-line Windows client, typing 'ls' really sends the FTP command 'NLST'. So when you type 'ls -la', it doesn't mean 'verbosely list all files'. According to RFCs, it means 'list the file called -la' . So you get what you asked for. If no file is called '-la', you get nothing. If you want to play with regular expressions and switches, you should type 'dir' (which is translated to 'LIST') instead. 'dir -la' is ok. This is a bit illogical and that brain damage is specific to Microsoft's command-line FTP client. If you really want 'ls' to parse options, you can start pure-ftpd with the -b (broken) switch. * Global bandwidth limitation. -> How do I limit the *total* bandwidth for FTP? Pure-FTPd can limit bandwidth usage of every session. But limiting the total bandwidth is intentionally not implemented, because most operating systems already have very efficient algorithms to handle bandwidth throttling. Here's an example with Linux. 1) Have a look at /proc/sys/net/ipv4/ip_local_port_range. You will see two numbers: this is the interval of local ports your Linux kernel will use for regular outgoing connections. The FTP ports you have to reserve for passive FTP must *not* be in this range. So if: "cat /proc/sys/net/ipv4/ip_local_port_range" returns "32768-61000", you can reserve ports 10000 to 20000 for your FTP server, but not 30000 to 40000. (alternatively, you can change the local port range) . 2) Change the first lines and save the following script: ---------------------------- Cut here ---------------------------- #! /bin/sh # Simple bandwidth limiter - # Change this to your link bandwidth # (for cable modem, DSL links, etc. put the maximal bandwidth you can # get, not the speed of a local Ethernet link) REAL_BW='10Mbit' # Change this to the bandwidth you want to allocate to FTP. # We're talking about megabits, not megabytes, so 80Kbit is # 10 Kilobytes/s FTP_BW='80Kbit' # Change this to your physical network device (or 'ppp0') NIC='eth0' # Change this to the ports you assigned for passive FTP FTP_PORT_LOW="10000" FTP_PORT_HIGH="20000" tc qdisc add dev "$NIC" root handle 1: cbq \ bandwidth "$REAL_BW" avpkt 1000 tc class add dev "$NIC" parent 1: classid 1:1 cbq bandwidth "$REAL_BW" \ rate "$REAL_BW" maxburst 5 avpkt 1000 tc class add dev "$NIC" parent 1:1 classid 1:10 cbq \ bandwidth "$REAL_BW" rate "$FTP_BW" maxburst 5 avpkt 1000 bounded tc qdisc add dev "$NIC" parent 1:10 sfq quantum 1514b tc filter add dev "$NIC" parent 1: protocol ip handle 1 fw flowid 1:10 iptables -t mangle -A OUTPUT -p tcp --sport 20:21 -j MARK --set-mark 1 iptables -t mangle -A OUTPUT -p tcp \ --sport "$FTP_PORT_LOW":"$FTP_PORT_HIGH" -j MARK --set-mark 1 ---------------------------- Cut here ---------------------------- 3) Make sure that you have the 'tc' command installed. If your Linux distro doesn't ship 'ip' and 'tc' commands, it really sucks and you must install a package called 'iproute2' to get them. 4) Start Pure-FTPd with the passive port range you assigned: /usr/local/sbin/pure-ftpd -p 10000:20000 -HBA 5) Run the script you created in step 2. It it doesn't work, check that QOS support was compiled in your Linux kernel. 6) Enjoy :) Also have a look at : http://www.docum.org http://www.shorewall.net/traffic_shaping.htm and http://talk.trekweb.com/~jasonb/articles/linux_tc_minihowto.shtml * Linux, NTFS and Pure-FTPd. -> On Linux, I can't transfer files from an NTFS partition. Keep in mind that the NTFS filesystem is still an experimental beast in Linux. Some basic operations are not implemented yet. Fortunately, a big effort is being made and Linux 2.5 has a new NTFS implementation that fully works with Pure-FTPd (try ./configure --without-sendfile, though) . And it is more reliable and really faster than the old one. And even more fortunately, the new NTFS implementation has been backported to recent 2.4.x kernels. Have a look at http://linux-ntfs.sf.net/ . * Slowdowns and lags. -> Some users complains that transferring large files doesn't work. Transfers are starting as expected, with a decent rate. But then, the speed dramatically decreases, there are some serious lags and they often must disconnect (or the client force them to do it, after a timeout) . The server is behind a firewall that filters incoming ICMP, but let FTP ports in. Don't, don't, don't filter ICMP. At least not blindly without understanding what you are filtering. ICMP is part of the TCP/IP specifications. Filtering it can have nasty side effects with no real win. If you even filter ICMP types 3 and 4, your firewall is definitely broken and this is probably why you have such troubles with transfers of large files. Please read these documents about ICMP filtering : http://www.phildev.net/mss/index.html http://alive.znep.com/~marcs/mtu/ http://www.freelabs.com/~whitis/isp_mistakes.html Also some hardware routers don't properly handle window scaling. Try to turn it off, for instance on Linux: sysctl -w net.ipv4.tcp_window_scaling=0 sysctl -w net.ipv4.tcp_bic=0 * Firewalls and TLS. -> My client is behind a stateful firewall doing applicative filtering (like IPTables with ip_conntrack_ftp or ip_nat_ftp) . Connections to an TLS enabled server doesn't work. Authentication works, but I'm unable to download files nor list directories. First, try to force your client to use the passive mode. In active mode, the server has to connect to the client (or the NAT gateway) on a dynamic port that is negotiated on the connection socket. But when TLS is used, that connection socket is encrypted, therefore no man-in-the middle can see what ports will be used to transfer data, including the firewall. There are some proposals to work around this problem, but neither popular clients nor common firewalls are aware of these tricks. Therefore, use the passive mode or switch to SSH. * TLS and error 00000000. -> My TLS-enabled client doesn't work. It outputs something like : "SSL connect: error:00000000:lib(0):func(0):reason(0)". What does it mean? This error is not very explicit. You get it from some Unix clients like LFTP. It actually means that there is a firewall or a NAT box between a TLS-enabled server and a TLS-enabled client, but that firewall is unable to handle encrypted FTP sessions. Unfortunately, there's no simple workaround against this. Try to switch your client to active mode and use 1:1 NAT, but TLS, firewalls and FTP don't mix very well. * Slow TLS operations. -> When clients connect with TLS encryption, listing directories and downloading files are slow operations. Nothing happens after a command is sent, things only start moving after a 5 secondes delay. Check the host name of your certificate. It should be a fully-qualified host name and if possible, it shouldn't be a CNAME entry. Also check your DNS cache servers. * Files getting renamed automatically (submitted by C. Jon Larsen) -> Sometimes when files get uploaded they are getting renamed to something like "pureftpd.3f3300d2.33.0001". What is causing this ? The ftp client that is being used to upload the files is using the STOU (Store Unique) FTP command instead of the STOR FTP command. If you check the ftp logfile you should see something like this in the logs: (user@a.b.c.d) [DEBUG] Command [stou] [file_name_from_the_client.ext] /var/ftp/ftpcustomer/pureftpd.3f3300d2.33.0001 uploaded (218168 bytes, 127.79KB/sec) The STOU command tells the ftp client to begin the transmission of the file to the remote site; the remote filename picked by the ftp server will be unique within in the current directory that the ftp client is using. The response from the server will include the filename. The ftp client has an option like "create unique files" or "upload file with a temporary name" enabled. You should have the ftp user uncheck this option. Trying to disable the STOU command on the server side is not a good idea or solution as some ftp clients will use STOU to upload a file with the temporary, unique name, and then rename the file once the upload is complete. This helps prevent failed uploads from leaving partial files around. opt/alt/openssl11/share/doc/alt-openssl11/FAQ000064400000000124152536464300014564 0ustar00The FAQ is now maintained on the web: https://www.openssl.org/docs/faq.html